2016-06-16 5 views
2

テーブルTAB1があり、簡単にできるGROUP BYの名前の列を必要としますが、次の日付の値24歳です。翌日の値が同じ値の場合にのみ値を加算する

あなたの助けを事前に

SELECT name, SUM(value) AS SUM_VALUE 
FROM TAB1 
WHERE value = 24 AND --next value of the same name with DATEADD(day,1,date) is 24 too 
GROUP BY name 

おかげのような聖は、INNERでペトル

name *date  *value 
    *************************** 
    text1 *2016-06-01 *8 
    text2 *2016-06-01 *4 
    text1 *2016-06-02 *24 
    text2 *2016-06-02 *8 
    text1 *2016-06-03 *24 
    text2 *2016-06-03 *24 
    text1 *2016-06-04 *6 
    text2 *2016-06-04 *24 
    text1 *2016-06-05 *24 
    text2 *2016-06-05 *24 
    text1 *2016-06-06 *24 
    text2 *2016-06-06 *8 
    text1 *2016-06-07 *24 
    text2 *2016-06-07 *24 
    text1 *2016-06-08 *6 
    text2 *2016-06-08 *24 
    text1 *2016-06-09 *24 
    text2 *2016-06-09 *24 

calculation algorithm 
1 - 48 => 0 
2 - 72 => 24 
1 - 72 => 24 
2 - 72 => 24 

The result should be 

    name *SUM_VALUE 
    ****************** 
    text1 *24 
    text2 *48 
+0

SQL Serverのバージョンをしてみましょうか?これらのすべてで、前の日の行と一致する自己結合を使用できます。 2012年以降、あなたは 'LAG'関数を使用して自己結合を避けることができます –

+0

2012バージョン...すぐに結合とLAG関数で選択を表示できますか? – Petr

答えて

1

に関しては、JOIN:CROSSで

SELECT name, 
     SUM([value]) AS SUM_VALUE 
FROM (
    SELECT DISTINCT y1.* 
    FROM YourTable y1 
    INNER JOIN YourTable y2 
     ON y2.name = y1.name AND 
      y2.[date] IN (DATEADD(day,1,y1.[date]),DATEADD(day,-1,y1.[date])) AND 
      y2.[value] = y1.[value] and y1.[value] = 24) as p 
GROUP BY name 

が適用されます。

SELECT y1.name, 
     SUM(y1.[value]) AS SUM_VALUE 
FROM YourTable y1 
CROSS APPLY (
    SELECT TOP 1 * 
    FROM YourTable 
    WHERE name = y1.name AND 
     [date] IN (DATEADD(day,1,y1.[date]),DATEADD(day,-1,y1.[date])) AND 
     [value] = y1.[value] 
    ) as p 
WHERE y1.[value] = 24 
GROUP BY y1.name 
すべてのための同じ

;WITH cte AS (
SELECT *, 
     CASE WHEN [value] IN (LAG([value],1,0) OVER (PARTITION BY name ORDER BY [date]), LEAD([value],1,0) OVER (PARTITION BY name ORDER BY [date])) THEN 1 ELSE 0 END as r 
FROM YourTable 
) 

SELECT name, 
     SUM([value]) as SUM_VALUE 
FROM cte 
WHERE r = 1 and [value] = 24 
GROUP BY name 

出力:SQL Server 2012のために

とアップあなたはLEADとLAGを使用することができ、現在の文字列のvalueは以前ととに類似している場合

name SUM_VALUE 
text1 48 
text2 72 

それはチェック次の値なら1rの列に入れます。

EDIT1

利用((SUM([value])/24)/3) * 24代わりのSUM([value])

EDIT2

私はあなたの質問からのデータで、これを使用します。

;WITH YourTable AS (
SELECT * 
FROM (VALUES 
('text1', '2016-06-01', 8), 
('text2', '2016-06-01', 4), 
('text1', '2016-06-02', 24), 
('text2', '2016-06-02', 8), 
('text1', '2016-06-03', 24), 
('text2', '2016-06-03', 24), 
('text1', '2016-06-04', 6), 
('text2', '2016-06-04', 24), 
('text1', '2016-06-05', 24), 
('text2', '2016-06-05', 24), 
('text1', '2016-06-06', 24), 
('text2', '2016-06-06', 8), 
('text1', '2016-06-07', 24), 
('text2', '2016-06-07', 24), 
('text1', '2016-06-08', 6), 
('text2', '2016-06-08', 24), 
('text1', '2016-06-09', 24), 
('text2', '2016-06-09', 24) 
) as t(name, [date], [value]) 
), cte AS (
SELECT *, 
     CASE WHEN [value] IN (LAG([value],1,0) OVER (PARTITION BY name ORDER BY [date]), LEAD([value],1,0) OVER (PARTITION BY name ORDER BY [date])) THEN 1 ELSE 0 END as r 
FROM YourTable 
) 

SELECT name, 
     ((SUM([value])/24)/3) * 24 as SUM_VALUE 
FROM cte 
WHERE r = 1 and [value] = 24 
GROUP BY name 

が出力:

name SUM_VALUE 
text1 24 
text2 48 
+0

それはほぼ良いですが、間違った説明があるかもしれません...日付で連続する24個の値のSUMの総計を取得する必要があります – Petr

+0

日付範囲内ですか? –

+0

なぜ期間ですか?シーケンスの最後を含む次の値24も持っている場合は、すべての値24を合計する必要があります。 – Petr

0

...私は結果を知っている

select a.[name], sum(a.[value]) as sum_value 
    from table a inner join (select b.[name], b.[date] from table b where b.[value] = 24) as c 
    on a.name = c.name and where dateadd(d, 1, a.date) = c.date 
    group by a.[name] 
関連する問題