1

次の名前と日付のペアごとに上位 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

簡単な方法があると思ったのですが、わかりません!

4

4 に答える 4

1

おそらく a を使用row_numberすると、subquery結果が得られます。

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))代わりに使用して、サブクエリの 1 つを削除できる場合があります。

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
于 2016-08-02T23:51:46.457 に答える
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
于 2016-08-02T23:54:33.520 に答える
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
于 2016-08-02T23:51:57.330 に答える
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;
于 2016-08-02T23:56:17.897 に答える