从datetime列获取Month列并计算条目

时间:2014-06-20 10:03:10

标签: sql tsql

我有下表:

| 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行。

我真的很感激,如果有人能帮助我或给我一个良好来源的链接,那么我可以自己阅读。

4 个答案:

答案 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 NULLCASTBIT为每个不同于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;