在列中显示选择结果

时间:2018-08-15 07:47:47

标签: sql sql-server

我有两个表,员工和工作时间。

员工:

ID   Name
001  Jack
002  Peter

工作时间:

 ID   Day    Hours
001  08/02     6
001  08/03     7
001  08/04     5
002  08/02     
002  08/03     4
002  08/04     6

如何获得类似结果

ID   Name   08/02   08/03   08/04
001  Jack     6       7       5
002  Peter    0       4       6

5 个答案:

答案 0 :(得分:0)

您可以尝试将JOIN条件汇总函数结合使用,将SUMCASE WHEN结合使用

CREATE TABLE Employee(
   ID VARCHAR(50),
   Name VARCHAR(50)
);


INSERT INTO Employee values ('001','Jack');
INSERT INTO Employee values ('002','Peter');

CREATE TABLE workinghours (
   ID VARCHAR(50),
   Day VARCHAR(50),
   Hours INT
);



INSERT INTO workinghours values ('001','08/02',6);
INSERT INTO workinghours values ('001','08/03',7);
INSERT INTO workinghours values ('001','08/04',5);
INSERT INTO workinghours values ('002','08/02',null);
INSERT INTO workinghours values ('002','08/03',4);
INSERT INTO workinghours values ('002','08/04',6);

查询1

SELECT t1.id,t1.name,
    SUM(CASE WHEN Day='08/02' then Hours else 0 end) '08/02',
    SUM(CASE WHEN Day='08/03' then Hours else 0 end) '08/03',   
    SUM(CASE WHEN Day='08/04' then Hours else 0 end) '08/04'       
FROM 
Employee t1 inner join workinghours t2 on t1.id = t2.id
GROUP BY t1.id,t1.name

Results

|  id |  name | 08/02 | 08/03 | 08/04 |
|-----|-------|-------|-------|-------|
| 001 |  Jack |     6 |     7 |     5 |
| 002 | Peter |     0 |     4 |     6 |

如果要动态创建列,可以尝试使用动态数据透视


创建SQL语法,然后使用execute函数动态执行它。

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);


SET @cols = STUFF((
            SELECT distinct ', SUM(CASE WHEN Day = '''+ Day + ''' then Hours else 0 end)' + ' as '''+Day+''''
            FROM workinghours
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)')
        ,1,1,'')


set @query = 'SELECT t1.id,
                     t1.name, ' + @cols + '  
                      FROM 
                      Employee t1 inner join workinghours t2 on t1.id = t2.id
                      GROUP BY t1.id,t1.name '
execute(@query)

答案 1 :(得分:0)

您应该使用PIVOT函数。

静态数据透视:

Read the docs

您可以静态旋转列

SELECT * FROM 
 (SELECT e.id, e.name, day, COALESCE(Hours,0) as Hours 
 FROM Employee e INNER JOIN workinghours w ON e.ID=w.ID) AS t
PIVOT (sum(Hours) FOR day IN ([08/02],[08/03],[08/04])) AS p;

结果:

|  id |  name | 08/02 | 08/03 | 08/04 |
|-----|-------|-------|-------|-------|
| 001 |  Jack |     6 |     7 |     5 |
| 002 | Peter |     0 |     4 |     6 |

DEMO

动态枢轴

也许您不想创建静态列表。根据{{​​3}},您也可以通过以下方式this post

DECLARE @cols AS NVARCHAR(MAX)='';
DECLARE @query  AS NVARCHAR(MAX)='';

SELECT @cols = @cols + QUOTENAME(Day) + ',' FROM 
 (SELECT DISTINCT Day FROM workinghours ) as wkh
SELECT @cols = SUBSTRING(@cols, 0, len(@cols)) --remove last ','

SET @query = 'SELECT name, ' + @cols + ' from 
            (SELECT e.id, e.name, day, COALESCE(Hours,0) as Hours FROM
             Employee e INNER JOIN workinghours w ON e.ID=w.ID) AS x
             PIVOT (sum(Hours) FOR day in (' + @cols + ')) AS p'


execute(@query);

结果:

|  id |  name | 08/02 | 08/03 | 08/04 |
|-----|-------|-------|-------|-------|
| 001 |  Jack |     6 |     7 |     5 |
| 002 | Peter |     0 |     4 |     6 |

重要:为了避免SQL注入,在创建动态列时使用QUOTENAME函数。 create a Dynamic Pivot table

答案 2 :(得分:0)

尝试使用数据透视:

with pcte as (SELECT t1.id,t1.name,day,hours       
FROM 
Employee t1 inner join workinghours t2 on t1.id = t2.id
)

select * from pcte
pivot(avg(hours) for day in ([08/02],[08/03],[08/04])) as pv

答案 3 :(得分:0)

如果您使用的是SQL Server 2005+,则可以使用var httpWebRequest = (HttpWebRequest)WebRequest.Create(webAPIEndpoint); httpWebRequest.Method = "GET"; var httpResponse = (HttpWebResponse)httpWebRequest.GetResponse(); return httpResponse; 函数将数据从行转换为列。

您可以使用PIVOTPIVOT关系运算符将UNPIVOT表达式更改为另一个表。 table-valued通过将表达式中的一列中的唯一值转换为输出中的多列来旋转PIVOT表达式,并对最终输出中需要的所有其余列值执行汇总操作。 table-valued通过将UNPIVOT表达式的列旋转为列值来执行与PIVOT相反的操作。

table-valued所提供的语法比在一系列复杂的PIVOT语句中可能指定的语法更简单易读。

SELECT...CASE

您可以找到更多详细信息here或参考类似的问题here

答案 4 :(得分:0)

请参阅this链接,您需要这样的视图:

SELECT Tbl_Employee.ID,
Tbl_Employee.Name,
Tbl_WorkingHours.Days,
Tbl_WorkingHours.Hours
FROM Tbl_Employee INNER JOIN Tbl_WorkingHours ON Tbl_Employee.ID = Tbl_WorkingHours.ID

,然后使用以下查询:

SELECT ID,
MAX(CASE WHEN (Days = '08/02') THEN Hours ELSE 0 END) AS '08/02',
MAX(CASE WHEN (Days = '08/03') THEN Hours ELSE 0 END) AS '08/03', 
MAX(CASE WHEN (Days = '08/04') THEN Hours ELSE 0 END) AS '08/04'
FROM  dbo.View_1
GROUP BY ID
ORDER BY ID