sql中不同类型的数据转换

时间:2016-12-13 11:30:02

标签: sql-server tsql

我正在寻找一个查询,我可以根据列值派生一个新列,如下例所示

P      X     Y    Z    A   B     C
1      1.1   2.1  1.3  1   Null  3
2      Null  1.4  3.1  2   4.7   1
3      2.2   Null 4.6  4   3.5   1 
4      Null  1.8  3.4  2   1.7   4

我想要显示如下所示;

P  Group   X    y   Z   A    B    C
1   Xgrp   1.1  -    -   -    -    - 
1   Ygrp    -  2.1   -   -    -    - 
1   Zgrp             1.3 -    -    -  
1   Agrp                 1   
1   Bgrp                     Null
1   Cgrp                          3

请帮帮我:)。

此致 安迪

2 个答案:

答案 0 :(得分:4)

我不确定你是如何定义这些破折号的,因此在下面的代码中会忽略它们。 ORDER BY子句中有一些额外的逻辑,以便在您的示例中显示结果。基本上,我们正在执行UNPIVOT来定义group值,然后再次执行PIVOT

DECLARE @DataSource TABLE
(
    [P] TINYINT
   ,[X] DECIMAL(9,1)
   ,[Y] DECIMAL(9,1)
   ,[Z] DECIMAL(9,1)
   ,[A] DECIMAL(9,1)
   ,[B] DECIMAL(9,1)
   ,[C] DECIMAL(9,1)
);

INSERT INTO @DataSource ([P], [X], [Y], [Z], [A], [B], [C])
VALUES (1, 1.1, 2.1, 1.3, 1, NULL, 3)
      ,(2, NULL, 1.4, 3.1, 2, 4.7, 1)
      ,(3, 2.2, NULL, 4.6, 4, 3.5, 1 )
      ,(4, NULL, 1.8, 3.4, 2, 1.7, 4);

SELECT *
FROM
(
    SELECT [P]
          ,[value]
          ,[column]
          ,[column] + 'grp'
    FROM @DataSource
    UNPIVOT
    (
        [value] FOR [column] IN ([X], [Y], [Z], [A], [B], [C])
    ) UNPVT
) DS ([P], [value], [column], [group])
PIVOT
(
    MAX([value]) FOR [column] IN ([X], [Y], [Z], [A], [B], [C])
) PVT
ORDER BY [P]
        ,CASE [group]
            WHEN 'Xgrp' THEN 1
            WHEN 'Ygrp' THEN 2
            WHEN 'Zgrp' THEN 3
            WHEN 'Agrp' THEN 4
            WHEN 'Bgrp' THEN 5
            WHEN 'Cgrp' THEN 6
        END 

enter image description here

答案 1 :(得分:0)

已发布的内容缺少某些行 - 特别是所有列都应为NULL的行(例如" Bgrp"记录其中P = 1)。

你可以在没有PIVOT或UNPIVOT的情况下获得你正在寻找的东西,只需要一个简单的CROSS JOIN,GROUP BY和CASE语句就可以了:

-- sample data
DECLARE @DataSource TABLE
(
    [P] TINYINT
   ,[X] DECIMAL(9,1)
   ,[Y] DECIMAL(9,1)
   ,[Z] DECIMAL(9,1)
   ,[A] DECIMAL(9,1)
   ,[B] DECIMAL(9,1)
   ,[C] DECIMAL(9,1)
);

INSERT INTO @DataSource ([P], [X], [Y], [Z], [A], [B], [C])
VALUES (1, 1.1, 2.1, 1.3, 1, NULL, 3)
      ,(2, NULL, 1.4, 3.1, 2, 4.7, 1)
      ,(3, 2.2, NULL, 4.6, 4, 3.5, 1 )
      ,(4, NULL, 1.8, 3.4, 2, 1.7, 4);

-- solution
SELECT 
  p, [group], 
  X = CASE [group] WHEN 'Xgrp' THEN MAX(X) END,
  Y = CASE [group] WHEN 'Ygrp' THEN MAX(Y) END,
  Z = CASE [group] WHEN 'Zgrp' THEN MAX(Z) END,
  A = CASE [group] WHEN 'Agrp' THEN MAX(A) END,
  B = CASE [group] WHEN 'Bgrp' THEN MAX(B) END,
  C = CASE [group] WHEN 'Cgrp' THEN MAX(C) END
FROM (VALUES ('Xgrp'),('Ygrp'),('Zgrp'),('Agrp'),('Bgrp'),('Cgrp')) groups([group])
CROSS JOIN @DataSource d
GROUP BY p, [group]
-- Uncomment this ORDER BY for testing:
--ORDER BY [P]
--        ,CASE [group]
--            WHEN 'Xgrp' THEN 1
--            WHEN 'Ygrp' THEN 2
--            WHEN 'Zgrp' THEN 3
--            WHEN 'Agrp' THEN 4
--            WHEN 'Bgrp' THEN 5
--            WHEN 'Cgrp' THEN 6
--        END;

结果

enter image description here