Sql 从datetime列和计数项中获取月份列

Sql 从datetime列和计数项中获取月份列,sql,tsql,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 |

我有下表:

| 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,然后count(case-when-timetowork-(case-when-timeworked然后0-end)=timetowork然后1-else 0-end)的方法作为'一月'
但是我的TSQL不是很好,代码根本不起作用。顺便说一句,使用这个我的Select命令大约有40行


如果有人能帮助我或给我一个链接到一个好的源代码,我将不胜感激。

正确的语法是条件聚合:

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;

如果我正确理解这个问题,那么戈登·林诺夫的回答是一个良好的开端,但没有涉及“全天休假”


此方法解决了问题?

可以使用位逻辑删除
案例

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为空
:将
转换为
对于0以外的每一个值返回1,
1位
反转这些值

月份过滤器为:

(1 - CAST(MONTH(DateA) - %month% as bit))
使用与之前相同的想法,此公式仅在给定的月份返回1(强制转换每隔一个月返回1,而
1位
反转该结果)


将这两个公式相乘,我们只有给定月份的休息日

您也可以使用pivot获得所需的结果。您可以在此处获得有关pivot的更多信息

您还可以使用以下查询获取输出。我只在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;
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;