SELECT TOP N具有不同/唯一的字段值

时间:2017-06-15 20:11:06

标签: sql tsql

根据我之前question的回答。我最终得到的结果如下:

PartyName   Risk    SubTotal    Total   

A           High    100         280
B           Med     25          45
A           Low     30          280
A           Med     70          280
B           Low     10          45
C           High    110         170
C           Med     60          170
D           Low     30          30
A           Med     80          280
B           Low     10          45

我需要选择具有最高金额的SELECT TOP N唯一PartyName,即如果N = 2,结果应为:

PartyName   Risk    SubTotal    Total   

A           High    100         280
A           Low     30          280
A           Med     70          280
C           High    110         170
C           Med     60          170
A           Med     80          280

所有具有最高N Total值的条目。

试过这个:

SELECT DISTINCT TOP(10) s.PartyName, s.Risk, s.SubTotal, s2.Total
FROM 
    (SELECT PartyName, Risk, SUM(CAST(Amount AS DECIMAL)) SubTotal
    FROM CustomerData
    GROUP BY PartyName, Risk) S
LEFT JOIN
    (SELECT PartyName, SUM(CAST(Amount AS DECIMAL)) Total
    FROM CustomerData
    GROUP BY PartyName) S2 
ON S.PartyName = S2.Partyname

但不起作用

3 个答案:

答案 0 :(得分:1)

离开我的头顶,也许是这样的:

if object_id('tempdb.dbo.#test') is not null drop table #test
create table #test
(
    partyname varchar(50),
    Risk varchar(50), 
    amount int
)

insert into #test
select 'A','High',50
union all select 'B','Med',  15
union all select 'A','Low',   12
union all select 'A','Med' ,  43
union all select 'B','Low' ,   65
union all select 'C','High',    12
union all select 'C','Med' ,   789
union all select 'D','Low' ,   12
union all select 'A' ,'Med',    34
union all select 'B' ,'Low',    43

SELECT
    main.PartyName, 
    main.Risk, 
    main.SubTotal, 
    TotalValues.Total 
FROM
    --get party+risk+subtotal
    (
            SELECT PartyName, Risk, SUM(CAST(Amount AS DECIMAL)) SubTotal
            FROM #test
            GROUP BY PartyName, Risk 
     ) main
--get total by partyname with a rownum to get top N, where N=2
INNER JOIN 
    (SELECT
        b.partyName, b.Total, row_number() over (order by Total desc) as rid
    FROM 
            (
                SELECT b.PartyName, SUM(CAST(Amount AS DECIMAL)) as Total  
                FROM #test b
                group by b.PartyName
            )  as b
    ) as TotalValues
    on TotalValues.partyName = main.partyName
    and TotalValues.rid <= 2 --n = 2
order by 
    main.partyname,
    TotalValues.Total

答案 1 :(得分:0)

我认为这个版本应该做你想要的:

SELECT TOP (10) WITH TIES PartyName, Risk,
       SUM(CAST(Amount AS DECIMAL)) as SubTotal,
       MAX(SUM(CAST(Amount AS DECIMAL))) OVER (PARTITION BY PartyName) as Total
FROM CustomerData
GROUP BY PartyName, Risk
ORDER BY Total DESC, PartyName;

编辑:

上面给出了与第10行绑定的所有行。如果您希望所有行都包含10个不同的值,请让我们使用DENSE_RANK()

SELECT cd.*
FROM (SELECT cd.*, DENSE_RANK() OVER (ORDER BY Total DESC) as seqnum
      FROM (SELECT TOP (10) WITH TIES PartyName, Risk,
                   SUM(CAST(Amount AS DECIMAL)) as SubTotal,
                   MAX(SUM(CAST(Amount AS DECIMAL))) OVER (PARTITION BY PartyName) as Total
            FROM CustomerData
            GROUP BY PartyName, Risk
           ) cd
     ) cd
WHERE seqnum <= 10
ORDER BY Total DESC, PartyName;

答案 2 :(得分:0)

首先我们得到一组总数据,然后我们找到感兴趣的总数范围,最后我们得到结果......

未测试:

WITH mAgg AS (SELECT partyName
                  , Risk
                  , sum(cast(amount as decimal(10,2)) over (partition by partyName, Risk) as subTotal
                  , sum(cast(amount as decimal(10,2)) over (partition by partyName) as Total
             FROM CustomerData),

  mRange as (SELECT distinct top 2 total from mAgg order by total desc)


SELECT * FROM mAgg where Total >=  (SELECT min(total) 
                                   FROM mRange))

或者也许我们可以将dense_rank()覆盖(分区按总desc),然后得到任何等级为&gt; = 2或N ...