我有下表:
| ID | Name | DateA | TimeToWork | TimeWorked |
|:--:|:----:|:----------:|:----------:|:----------:|
| 1 |Frank | 2013-01-01 | 8 | 5 |
| 2 |Frank | 2013-01-02 | 8 | NULL |
| 3 |Frank | 2013-01-03 | 8 | 7 |
| 4 |Jules | 2013-01-01 | 4 | 9 |
| 5 |Jules | 2013-01-02 | 4 | NULL |
| 6 |Jules | 2013-01-03 | 4 | 3 |
桌子很长,每个人每年都有一个入口。对于每个人,我都有他工作的日期(DateA
),他必须根据合同工作的时间(TimeToWork
)和他工作的时间(TimeWorked
)。正如你所看到的,有些日子,一个人在他必须的那一天没有工作。这是一个人加班一整天。
我试图完成的是从上面的第一个中获取下表。
| Name | January | Feburary | March | ... | Sum |
|:----:|:----------:|:--------:|:-----:|:---:|:---:|
|Frank | 2 | 0 | 1 | ... | 12 |
|Jules | 5 | 1 | 3 | ... | 10 |
对于每个月,我想计算一个人休假全天的所有日子,并在Sum
列中总结。
我试过像Select (case when Datetime(month, DateA = 1 then count(case when timetowork - (case when timeworked then 0 end) = timetowork then 1 else 0 end) end) as 'January'
这样的东西,但是我的TSQL并不是那么好,而且代码根本不起作用。顺便说一下,使用我的select命令大概是40行。
我真的很感激,如果有人能帮助我或给我一个良好来源的链接,那么我可以自己阅读。
答案 0 :(得分:1)
如果我理解这个问题,那么Gordon Linoff的回答是一个良好的开端,但并不能解决全天的问题。
select Name,
sum(case when month(DateA) = 01 and TimeWorked is null then 1 else 0 end) as Jan,
sum(case when month(DateA) = 02 and TimeWorked is null then 1 else 0 end) as Feb,
...
sum(case when month(DeteA) = 12 and TimeWorked is null then 1 else 0 end) as Dec,
sum(case when TimeWorked is null then 1 else 0 end) as Sum
from table T
where year(DateA) = 2013
group by name
这个方法解决了这个问题吗?
答案 1 :(得分:0)
正确的语法是条件聚合:
select name,
sum(case when month(datea) = 1 then timeworked else 0 end) as Jan,
sum(case when month(datea) = 2 then timeworked else 0 end) as Feb,
. . .
sum(case when month(datea) = 12 then timeworked else 0 end) as Dec,
sum(timeworked)
from table t
where year(datea) = 2013
group by name;
答案 2 :(得分:0)
可以使用位逻辑
删除CASE
SELECT name
, January = SUM((1 - CAST(MONTH(DateA) - 1 as bit))
* (1 - CAST(COALESCE(TimeWorked, 0) as bit)))
, February = SUM((1 - CAST(MONTH(DateA) - 2 as bit))
* (1 - CAST(COALESCE(TimeWorked, 0) as bit)))
...
, December = SUM((1 - CAST(MONTH(DateA) - 12 as bit))
* (1 - CAST(COALESCE(TimeWorked, 0) as bit)))
, Total = SUM((1 - CAST(COALESCE(TimeWorked, 0) as bit)))
FROM table1
GROUP BY name;
要检查公式是否有假日:
(1 - CAST(COALESCE(TimeWorked, 0) as bit))
相当于TimeWorked IS NULL
:CAST
到BIT
为每个不同于0的值返回1,1 - BIT
会反转这些值。
月份过滤器是:
(1 - CAST(MONTH(DateA) - %month% as bit))
使用与此公式之前相同的想法仅在给定月份返回1(每隔一个月投出1次,1 - BIT
反转结果)
将两个公式相乘,我们只在给定月份休假
答案 3 :(得分:0)
您也可以使用pivot来获得所需的结果。您可以在http://technet.microsoft.com/en-in/library/ms177410(v=sql.105).aspx
获取有关透视的更多信息您还可以使用以下查询获取输出。我只做了4月份。你可以把它延长到12月。
Select [Name], [January], [February], [March], [April]
From
(
Select Name, MName, DaysOff from
(
select Name, DATENAME(MM, dateA) MName,
count(case isnull(timeworked,0) when 0 then 1 else null end) DaysOff
from tblPivot
Where Year(DateA) = 2013
group by Name, DATENAME(MM, dateA)
) A ) As B
pivot(Count(DaysOff)
For MName in ([January], [February],[March],[April])
) As Pivottable;