sqlserver 行轉列、字符串行轉列、自動生產行轉列腳本


行轉列,老生常談的問題。這里總結一下網上的方法。

1、生成測試數據:

CREATE TABLE human(
    name NVARCHAR(5),    --姓名
    norm NVARCHAR(5),    --指標
    score INT ,            --分數
    grade NVARCHAR(2)    --等級
)
GO
INSERT INTO human(name,norm,score,grade)VALUES
('旺仔','考勤',56,'c'),
('旺仔','生產',85,'b'),
('旺仔','技術',95,'a'),
('小傑','考勤',66,'a'),
('小傑','生產',77,'b'),
('小傑','技術',88,'c'),
('玉紅','考勤',92,'j'),
('玉紅','生產',73,'k'),
('玉紅','技術',81,'m')

查詢數據:

注意:這里的score是數值類型列,而grade是字符串類型的列

 

2、利用case when 語句完成行轉列,其中行轉列之后的列的屬性是數值類型

SELECT 
    name,
    SUM(CASE WHEN norm = '考勤' THEN score ELSE 0 END) AS 考勤,
    SUM(CASE WHEN norm = '生產' THEN score ELSE 0 END) AS 生產,
    SUM(CASE WHEN norm = '技術' THEN score ELSE 0 END) AS 技術
FROM dbo.human
GROUP BY name

結果:

 

3、利用case when 語句完成行轉列,其中行轉列之后的列的屬性是字符串類型

又分為兩種情況,a:是借用for xml path 拼接字符串,b:巧妙的借用max()函數可以對字符串進行運算的特點進行篩選

a:借用for xml path 拼接字符串

SELECT  name ,
        ( SELECT    grade + ''
          FROM      dbo.human
          WHERE     name = a.name
                    AND norm = '考勤'
        FOR
          XML PATH('')
        ) AS 考勤 ,
        ( SELECT    grade + ''
          FROM      dbo.human
          WHERE     name = a.name
                    AND norm = '生產'
        FOR
          XML PATH('')
        ) AS 生產 ,
        ( SELECT    grade + ''
          FROM      dbo.human
          WHERE     name = a.name
                    AND norm = '技術'
        FOR
          XML PATH('')
        ) AS 技術
FROM    dbo.human a
GROUP BY name;

結果:

b:巧妙的借用max()(或min())函數可以對字符串進行運算的特點進行篩選

SELECT  name ,
        MAX( CASE WHEN a.norm = '考勤' THEN a.grade ELSE '' END ) AS 考勤,
        MAX( CASE WHEN a.norm = '生產' THEN a.grade ELSE '' END ) AS 生產,
        MAX( CASE WHEN a.norm = '技術' THEN a.grade ELSE '' END ) AS 技術
FROM    dbo.human a
GROUP BY name;

結果:

 

3、實際生產過程中會碰到這種情況:norm列的值有很多種情況,比如幾十、上百個,難道我們一一手寫嗎?不,我們可以考慮使用拼接字符串的方式,動態實現行轉列

DECLARE @sql NVARCHAR(MAX);
SELECT  @sql = 'select name,
';

SELECT  @sql = @sql + 'max(case when a.norm = ''' + a.norm
        + ''' then a.grade ELSE '''' END ' + ') as ' + QUOTENAME(a.norm) + ',
'
FROM    ( SELECT DISTINCT
                    norm
          FROM      dbo.human
        ) a; 

SELECT  @sql = SUBSTRING(@sql, 1, LEN(@sql) - 3);

SELECT  @sql = @sql + '
FROM    dbo.human a
GROUP BY name;';

SELECT  @sql;
EXEC (@sql);

首先觀察一下我們自動拼接出來的sql語句:

完美!拼接的語句正式我們所希望的,所以結果也不出所料:

 

4、pivot新特性實現行轉列,針對行轉列后,列的屬性是數值類型的情況,這里指score

SELECT  *
FROM    ( SELECT    name ,
                    norm ,
                    score
          FROM      dbo.human
        ) t PIVOT( SUM(score) FOR norm IN ( 考勤, 生產, 技術 ) ) AS pvt;

結果:

5、pivot新特性實現行轉列,針對行轉列后,列的屬性是字符串類型的情況,這里指score

SELECT  *
FROM    ( SELECT    name ,
                    norm ,
                    grade
          FROM      dbo.human
        ) t PIVOT( MAX(grade) FOR norm IN ( 考勤, 生產, 技術 ) ) AS pvt;

 

6、同理,我們也可以通過拼接字符串的形式來組織pivot語句生成自動行轉列的腳本。好動手的童鞋趕快動起來吧。

如果您有疑問,歡迎評論區交流討論

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM