SQL Server 2008 R2:VARCHAR列上的数据透视表

时间:2018-02-15 09:40:46

标签: sql sql-server-2008-r2 pivot-table

表格

CREATE TABLE EMPDetails
(
    ID int,
    EmpName varchar(20),
    ColumnName varchar(20),
    ColumnValue varchar(20)
);

记录

INSERT INTO EMPDetails Values(1,'S','Company','Microsoft');
INSERT INTO EMPDetails Values(1,'S','Profession','Database');
INSERT INTO EMPDetails Values(1,'S','Location','USA');
INSERT INTO EMPDetails Values(1,'S','Company','Unisys');
INSERT INTO EMPDetails Values(1,'S','Company','TATA');

INSERT INTO EMPDetails Values(2,'U','Company','Microsoft');
INSERT INTO EMPDetails Values(2,'U','Profession','Software');
INSERT INTO EMPDetails Values(2,'U','Location','UK');
INSERT INTO EMPDetails Values(2,'U','Company','DXC');
INSERT INTO EMPDetails Values(2,'U','Company','AOL');

INSERT INTO EMPDetails Values(3,'R','Company','Microsoft');
INSERT INTO EMPDetails Values(3,'R','Profession','Software');
INSERT INTO EMPDetails Values(3,'R','Location','UK');
INSERT INTO EMPDetails Values(3,'R','Company','AOL');

我的尝试

条件1 Company = 'Microsoft' AND Profession = 'Database'

预期结果:

ID  EmpName Company     Profession  Location
-----------------------------------------
1   S       Microsoft   Database    USA

查询:

SELECT *
FROM 
(
  SELECT ID, EmpName,ColumnValue, ColumnName
  FROM EMPDetails
) src
PIVOT
(
  MAX(ColumnValue) /*OR MIN()*/
  FOR ColumnName in ([Company], [Profession], [Location])
) piv
WHERE Company = 'Microsoft' AND Profession = 'Database'  

条件2 Company = 'Microsoft' AND Profession = 'Software'

预期结果:

ID  EmpName Company     Profession  Location
-----------------------------------------
3   R       Microsoft   Software    UK
2   U       Microsoft   Software    UK

查询:

SELECT *
FROM 
(
  SELECT ID, EmpName,ColumnValue, ColumnName
  FROM EMPDetails
) src
PIVOT
(
  MAX(ColumnValue) /*OR MIN()*/
  FOR ColumnName in ([Company], [Profession], [Location])
) piv
WHERE Company = 'Microsoft' AND Profession = 'Software'

问题:如果我使用条件1的MIN()聚合函数,那么将获得结果但不会使用MAX()并且条件2的结果相反。为什么?

1 个答案:

答案 0 :(得分:1)

您可以GROUP BY员工并在HAVING条款中使用条件计数,以使员工满足标准:

SELECT ID, EmpName      
FROM EMPDetails 
GROUP BY ID, EmpName
HAVING COUNT(CASE 
                WHEN ColumnName = 'Company' AND 
                     ColumnValue = 'Microsoft' THEN 1 
             END) > 0
       AND 
       COUNT(CASE 
                WHEN ColumnName = 'Profession' AND 
                ColumnValue = 'Database' THEN 1 
             END) > 0

以上查询选择Microsoft作为Company Database作为Profession的员工。

<强>输出:

ID  EmpName
------------
1   S

您现在可以使用条件聚合来转动员工行:

SELECT ID, EmpName,
       'Microsoft' AS Company,
       'Database' AS Profession,
       MAX(CASE WHEN ColumnName = 'Location' THEN ColumnValue END) AS Location
FROM EMPDetails 
GROUP BY ID, EmpName
HAVING COUNT(CASE 
                WHEN ColumnName = 'Company' AND 
                     ColumnValue = 'Microsoft' THEN 1 
             END) > 0
       AND 
       COUNT(CASE 
                WHEN ColumnName = 'Profession' AND 
                     ColumnValue = 'Database' THEN 1 
             END) > 0

无需为公司或专业价值执行汇总,因为保证期望值属于员工组。

<强>输出:

ID  EmpName Company     Profession  Location
-----------------------------------------
1   S       Microsoft   Database    USA

要获得第二个结果集,您只需将Database替换为Software

SELECT ID, EmpName,
       'Microsoft' AS Company,
       'Software' AS Profession,
       MAX(CASE WHEN ColumnName = 'Location' THEN ColumnValue END) AS Location
FROM EMPDetails 
GROUP BY ID, EmpName
HAVING COUNT(CASE 
                WHEN ColumnName = 'Company' AND 
                     ColumnValue = 'Microsoft' THEN 1 
             END) > 0
       AND 
       COUNT(CASE 
                WHEN ColumnName = 'Profession' AND 
                     ColumnValue = 'Software' THEN 1 
             END) > 0

<强>输出:

ID  EmpName Company     Profession  Location
---------------------------------------------
3   R       Microsoft   Software    UK
2   U       Microsoft   Software    UK