2016-08-02 4 views
1

次のように、Name-dateeのペアごとに上位3つの値のみを返すにはどうすればよいですか?Sqlロールアップグループごとにトップ3を選択

DECLARE @t TABLE(NAME NVARCHAR(MAX),datee date,val money) 

insert INTO @t SELECT 'a','2012-01-02',100 
insert INTO @t SELECT 'a','2012-01-02',100 
insert INTO @t SELECT 'a','2012-01-03',100 
insert INTO @t SELECT 'a','2012-01-05',150 
insert INTO @t SELECT 'a','2012-01-06',200 
insert INTO @t SELECT 'b','2012-01-07',200 
insert INTO @t SELECT 'b','2012-01-07',400 
insert INTO @t SELECT 'b','2012-01-09',500 
insert INTO @t SELECT 'b','2012-01-12',600 
insert INTO @t SELECT 'b','2012-01-13',100 

SELECT Name, datee, SUM(val) sumval from @t 
GROUP BY rollup(NAME ,datee) 
order by Name, sumval desc 

この現在のバージョンを返します:

Name datee  sumval 
NULL NULL  2450.00 
a  NULL  650.00 
a  2012-01-02 200.00 
a  2012-01-06 200.00 
a  2012-01-05 150.00 
a  2012-01-03 100.00 
b  NULL  1800.00 
b  2012-01-07 600.00 
b  2012-01-12 600.00 
b  2012-01-09 500.00 
b  2012-01-13 100.00 

私は返すしたいと思います:

Name datee  sumval 
NULL NULL  2450.00 
a  NULL  650.00 
a  2012-01-02 200.00 
a  2012-01-06 200.00 
a  2012-01-05 150.00 
b  NULL  1800.00 
b  2012-01-07 600.00 
b  2012-01-12 600.00 
b  2012-01-09 500.00 

私はそこに簡単な方法だろうが、それを把握することはできませんと思いました!

答えて

1
;with cteBase as (
Select Name 
     ,datee 
     ,sumval=SUM(val) 
     ,rowNr=ROW_NUMBER() over (Partition By Name Order by sum(Val) Desc) 
From @t 
GROUP BY rollup(NAME ,datee) 
) 
Select * 
From cteBase 
Where RowNr<=4 
order by Name, sumval desc 

戻り

Name datee  sumval rowNr 
NULL NULL  2450.00 1 
a  NULL  650.00 1 
a  2012-01-02 200.00 2 
a  2012-01-06 200.00 3 
a  2012-01-05 150.00 4 
b  NULL  1800.00 1 
b  2012-01-07 600.00 2 
b  2012-01-12 600.00 3 
b  2012-01-09 500.00 4 
+0

これは完全に機能し、編集なしで私のために働いていた唯一のものです。 – conor

1

おそらくsubqueryrow_numberを使用すると、あなたの結果を達成することができます

select * 
from (
    select *, 
      row_number() over (partition by name order by sumval desc) rn 
    from (
     select Name, datee, SUM(val) sumval 
     from @t 
     group by rollup(NAME ,datee) 
     order by Name, sumval desc 
    ) t 
) t 
where rn <= 3 or datee is null 

あなたが代わりにrow_number() over (partition by name order by sum(val))を使用して、サブクエリのいずれかを削除することができるかもしれません。

select * 
from (
     select Name, datee, SUM(val) sumval, 
     row_number() over (partition by name order by SUM(val) desc) rn 
     from @t 
     group by rollup(NAME ,datee) 
     order by Name, sumval desc 
) t 
where rn <= 3 or datee is null 
0

あなたは、あなたは、サブクエリにこれをラップする必要があり、何が必要数以上の任意の行をフィルタリングしたい、インデックスへの出力をRANK()ROW_NUMBER()を使用する必要があります。このよう

SELECT 
    t.Name, 
    t.date, 
    t.sumval 
FROM 
(
    SELECT 
     Name, 
     date, 
     SUM(val) sumval, 
     ROW_NUMBER() OVER (ORDER BY sumval, PARTITION BY name) RowId 
    from @t GROUP BY rollup(NAME ,datee) 
) t 
WHERE RowId <= 3 
order by Name, sumval desc 
+0

あなたは、日付によってパーティションのは嫌だ、ということ各行に行番号1を与えます。 – mrtig

0

は、これは、rollupの大きな複雑です。この意志は、(私は今テストすることはできません)

SELECT t.* 
FROM (SELECT Name, datee, SUM(val) as sumval, 
      ROW_NUMBER() OVER (PARTITION BY Name ORDER BY SUM(val) DESC) as seqnum 
     FROM @t t 
     GROUP BY rollup(NAME, datee) 
    ) t 
WHERE seqnum <= 3 or Datee is NULL 
ORDER BY Name, sumval desc; 

を問題が解決しない場合:私は、次のように動作すると思わ

SELECT Name, datee, sumval 
FROM (SELECT Name, datee, SUM(sumval) as sumval, MAX(seqnum) as seqnum 
     FROM (SELECT Name, datee, SUM(val) as sumval, 
        ROW_NUMBER() OVER (PARTITION BY Name ORDER BY SUM(val) DESC) as seqnum 
      FROM @t t 
      GROUP BY Name, datee 
      ) t 
     GROUP BY rollup(NAME, datee) 
    ) t 
WHERE seqnum <= 3 or Date is NULL 
ORDER BY Name, sumval desc; 
関連する問題