PIVOT SQL返回工作日的重复行

时间:2018-08-10 17:34:33

标签: sql sql-server

我有一个表,其中包含一些数据,如下所示:

+-----+-------------+---------------------+----------+-----------+ 
| id  |    name     |        date         |  start   |    end    | 
+-----+-------------+---------------------+----------+-----------+ 
| 123 | marsGuy     | 2018-01-03 00:00:00 | 10:00:00 | 16:00:00  | 
| 123 | marsGUy     | 2018-01-04 00:00:00 | 10:00:00 | 12:00:00  | 
| 124 | snickersGuy | 2018-01-03 00:00:00 | 10:00:00 | 18:00:00  | 
+-----+-------------+---------------------+----------+-----------+ 

我目前正在使用PIVOT SQL,并尝试从Fri-Thur中提取数据并生成各个列,并显示一个人在该周内的工作时间。因此,对于上述情况,我希望marsGuy排成一排,因为如果您查看他对应的日期列,他将在同一周工作两次。

基于下面查询中case语句中的一些规则,我希望他们在计算出他们工作了多少小时后使用某些单词。

因此,如果他们做了8小时(或以上),则在该特定日期下的一行将填充“ highAf”一词,如下所示:

+-------------+-----+-----+-----+--------+-------+-----+------+
|    name     | fri | sat | sun |  mon   |  tue  | wed | thur |
+-------------+-----+-----+-----+--------+-------+-----+------+
| marsGuy     |     |     |     | good   | small |     |      |
| snickersGuy |     |     |     | highAf |       |     |      |
+-------------+-----+-----+-----+--------+-------+-----+------+

查询:

select distinct
    name,
    posId,
    [6] as Fri,
    [7] as Sat,
    [1] as Sun,
    [2] as Mon,
    [3] as Tue,
    [4] as Wed,
    [5] as Thu
from 
(
select
    case 
        when DATEDIFF(HOUR, start, end) >= 8.5 then 'highAf'
        when DATEDIFF(HOUR, start, end) >= 6.5 then 'good' 
        when DATEDIFF(HOUR, start, end) >= 4 then  'moderate'
        when DATEDIFF(HOUR, start end) >= 2 then 'small'
    end as hourWorked,
    datepart(weekday, date) as day_of_week
from MyTable

) as p pivot
( max(hourWorked) for day_of_week in ([1],[2],[3],[4],[5],[6],[7])
) as pivottbl

我想我真的很近。预先谢谢你。

2 个答案:

答案 0 :(得分:1)

我通过选择import { AdminRewardPage } from '/somePath' 并确保在子查询中选择了name使其工作。例如:

name

产生输出:

DECLARE @MyTable TABLE (id int, [name] varchar(100), [date] datetime, [start] time(0), [end] time(0))
INSERT INTO @MyTable VALUES
 (123, 'marsGuy',     '2018-01-03 00:00:00', '10:00:00', '16:00:00')
,(123, 'marsGUy',     '2018-01-04 00:00:00', '10:00:00', '12:00:00')    
,(124, 'snickersGuy', '2018-01-03 00:00:00', '10:00:00', '18:00:00')
,(124, 'snickersGuy', '2018-01-01 00:00:00', '10:00:00', '19:00:00')

select distinct
    [name],
    --posId,
    [6] as Fri,
    [7] as Sat,
    [1] as Sun,
    [2] as Mon,
    [3] as Tue,
    [4] as Wed,
    [5] as Thu
from 
(
select
    [name],
    case 
        when DATEDIFF(MINUTE, [start], [end]) >= 510 then 'highAf'
        when DATEDIFF(MINUTE, [start], [end]) >= 390 then 'good' 
        when DATEDIFF(MINUTE, [start], [end]) >= 240 then  'moderate'
        when DATEDIFF(MINUTE, [start], [end]) >= 120 then 'small'
    end as hourWorked,
    datepart(weekday, date) as day_of_week
from @MyTable

) as p pivot
( max(hourWorked) for day_of_week in ([1],[2],[3],[4],[5],[6],[7])
) as pivottbl

答案 1 :(得分:0)

我会使用apply

select name, max(case when day_of_week = 1 then hourWorked end),
             max(case when day_of_week = 2 then hourWorked end),
             max(case when day_of_week = 3 then hourWorked end),
             max(case when day_of_week = 4 then hourWorked end),
             max(case when day_of_week = 5 then hourWorked end),
             max(case when day_of_week = 6 then hourWorked end),
             max(case when day_of_week = 7 then hourWorked end)
from MyTable t cross apply
     ( values ( (case when DATEDIFF(HOUR, start, [end]) >= 8.5 then 'highAf'
                      when DATEDIFF(HOUR, start, [end]) >= 6.5 then 'good' 
                      when DATEDIFF(HOUR, start, [end]) >= 4   then 'moderate'
                      when DATEDIFF(HOUR, start, [end]) >= 2   then 'small' 
                  end), datepart(WEEKDAY, [date])   
              )
     ) tt (hourWorked, day_of_week)
group by name;