我对SQL非常熟悉。我使用的是SQL Server 2012。
我有这张桌子:
|Id | SiteId| SiteDesc |IsNormal| DateReview |FrequencyId|
|3379| 5| colon | 1 | 2016-09-10 00:00:00.000| 1 |
|3381| 5| colon | 0 | 2016-09-15 00:00:00.000| 1 |
|3382| 5| colon | 1 | 2016-09-21 00:00:00.000| 1 |
|3489| 5| colon | 0 | 2016-08-10 00:00:00.000| 1 |
|3851| 5| colon | 1 | 2016-08-16 00:00:00.000| 1 |
|3537| 2| dogon | 1 | 2016-05-05 00:00:00.000| 1 |
|3863| 2| dogon | 1 | 2016-05-20 00:00:00.000| 1 |
IsNormal
列属于BIT
数据类型。
我需要按SiteId
和DateReview
(仅限月份和年份)对表格进行分组。如果在IsNormal
列中至少有一行具有属性false,则在分组表中它必须为False。
以下是所需的分组表:
| SiteId| SiteDesc |IsNormal| DateReview |FrequencyId|
| 5| colon | 0 | 2016-09-10 00:00:00.000| 1 |
| 5| colon | 0 | 2016-08-10 00:00:00.000| 1 |
| 2| dogon | 1 | 2016-05-05 00:00:00.000| 1 |
答案 0 :(得分:6)
SQL Server无法按原样聚合bit
列,因此请先将其转换为int
,然后使用MIN
,然后将其强制转换回bit
。
要按月分组,我使用以下公式:
DATEADD(month, DATEDIFF(month, '20010101', DateReview), '20010101')
您可以选择任何锚定日期而不是“20010101”,它可以是该月的任何第一天。这个想法很简单。 DATEDIFF(month,...)
计算锚点日期与表格中的值之间的月数。这是整数 - 跨越月份的边界的次数。然后将此数字添加回锚定日期。此表达式的结果是截断到该月第一天的DateReview
的值。
<强>查询强>
SELECT
SiteId
,MIN(SiteDesc) AS SiteDesc
,CAST(MIN(CAST(IsNormal AS int)) AS bit) AS IsNormal
,MIN(DateReview) AS DateReview
,MIN(FrequencyId) AS FrequencyId
FROM T
GROUP BY
SiteId
,DATEADD(month, DATEDIFF(month, '20010101', DateReview), '20010101')
答案 1 :(得分:3)
使用year()
和month()
:
select SiteId, min(SiteDesc) as SiteDesc,
min(case when IsNormal = 0 then 0 else 1 end) as IsNormal,
min(DateReview) as DateReview,
min(FrequencyId) as FrequencyId
from t
group by SiteId, year(DateReview), month(DateReview)
order by min(DateReview) desc;
这只是使用年份和月份进行聚合。然后使用聚合函数拉取列值。对于DateReview
,相应的函数似乎为min()
。
答案 2 :(得分:0)
我也使用过这段代码。
select CAST(MONTH(SalesDate) AS VARCHAR(2)) + '-' + CAST(YEAR(SalesDate) AS VARCHAR(4)), sum(TSalesAmt) as 'GrandTotal' from CreditSales group by CAST(MONTH(SalesDate) AS VARCHAR(2)) + '-' + CAST(YEAR(SalesDate) AS VARCHAR(4))