2016-10-20 4 views
2

私はむしろSQLを漠然とよく知っています。月と年だけをグループ化する方法

|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データ型である:私はこのテーブルを持っているのSQL Server 2012

を使用しています。

SiteIdDateReview(月と年のみ)で表をグループ化する必要があります。 IsNormal列に少なくとも1つの行がプロパティ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  |  

は、事前にありがとうございます。

+1

@gauravグループで選択したアイテムは、グループまたは集計のいずれかでなければなりません。これはこのルールに合致しません。 – Richard

答えて

3

SQL Serverが集約ないbit列はそのままなので、最初に、そしてMINを使用intにキャストし、その後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

なぜGROUP BY YEAR(DateReview)、MONTH(DateReview) 'が好奇心ではないのか? – Eric

+1

@エリックこの場合は違いはありません。 'DATEDIFF'の式はより一般的です。 'month'ではなく' week'/'quarter' /' hour'/etcを他の間隔でグループ化することができます。 –

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()のように見えます。

関連する問題