在SQL Server数据库中选择具有最大值的行(来自组)

时间:2010-03-29 15:20:21

标签: sql-server tsql

我有一个大型数据库,正在整理数据报告。我已经聚合并汇总了许多表中的数据,以获得两个如下所示的表。

id | code | value          id | code | value
13 |  AA  | 0.5            13 |  AC  | 2.0
13 |  AB  | 1.0            14 |  AB  | 1.5
14 |  AA  | 2.0            13 |  AA  | 0.5
15 |  AB  | 0.5            15 |  AB  | 3.0
15 |  AD  | 1.5            15 |  AA  | 1.0

我需要获取一个id列表,其代码(从两个表中取代)具有最大值。

13 |  AC
14 |  AA
15 |  AB

有4-6,000条记录,无法更改原始表格。我不太担心性能,因为我只需要每年运行几次。

编辑: 让我看看我是否可以更清楚地解释一下,想象一下id是客户ID,代码是他们订购的人,价值是他们在那里花了多少钱。

我需要所有客户ID和客户花费最多的商店的清单(如果他们在两个不同的商店花费相同的商品名称,则为商店名称添加“ZZ”等值)。

2 个答案:

答案 0 :(得分:2)

试试这个:

DECLARE @Table1 table (id int, code char(2), value decimal(5,1))
INSERT @Table1 VALUES (13 ,  'AA'  , 0.5)
INSERT @Table1 VALUES (13 ,  'AB'  , 1.0)
INSERT @Table1 VALUES (14 ,  'AA'  , 2.0)
INSERT @Table1 VALUES (15 ,  'AB'  , 0.5)
INSERT @Table1 VALUES (15 ,  'AD'  , 1.5)

DECLARE @Table2 table (id int, code char(2), value decimal(5,1))
INSERT @Table2 VALUES (13 ,  'AC'  , 2.0)
INSERT @Table2 VALUES (14 ,  'AB'  , 1.5)
INSERT @Table2 VALUES (13 ,  'AA'  , 0.5)
INSERT @Table2 VALUES (15 ,  'AB'  , 3.0)
INSERT @Table2 VALUES (15 ,  'AA'  , 1.0)

SELECT
     dt.id, MAX(dt.code) AS code, sum(dt.value) as value
    from (select id, code, value
              from @Table1
              UNION ALL
              select
                  id, code, value
                  from @Table2
         ) dt
        group by dt.id
        order by id

输出:

id          code value
----------- ---- ---------------------------------------
13          AC   4.0
14          AB   3.5
15          AD   6.0

(3 row(s) affected)

我不确定你追求的是什么?这是每个id加上值的MAX代码。如果这不是你的意思,请更清楚地指出问题

OP编辑后的

编辑,使用与上面代码相​​同的表格:

;WITH AllTAbles AS
(select 
     id, code, value
     from @Table1
 UNION ALL
 select
     id, code, value
     from @Table2
)
, MaxValues AS
(SELECT
     dt.id, MAX(dt.value) as MaxValue, SUM(dt.value) AS SumValue
     from AllTAbles dt
     group by dt.id
)
, StoreCount AS
(SELECT
     a.id,a.Code, COUNT(*) AS StoreCount
     FROM AllTAbles            a
         INNER JOIN MaxValues  m ON a.id=m.id AND a.value=m.MaxValue
     GROUP BY a.id,a.Code
)
SELECT
    s.id
        ,CASE
             WHEN s.StoreCount=1 THEN s.Code
             ELSE 'ZZ'
         END AS code
        ,m.SumValue
    FROM StoreCount           s
        INNER JOIN MaxValues  m ON s.id=m.id
    ORDER BY s.id

输出:

id          code SumValue
----------- ---- ----------
13          AC   4.0
14          AA   3.5
15          AB   6.0

(3 row(s) affected)
OP没有说SQL Server的版本,所以这里是一个不使用CTE的SQL Server 2005之前的版本,它的输出与上面的CTE版本相同:

SELECT
    s.id
        ,CASE
             WHEN s.StoreCount=1 THEN s.Code
             ELSE 'ZZ'
         END AS code
        ,s.SumValue
    FROM (SELECT           
              a.id,a.Code, COUNT(*) AS StoreCount, m.SumValue
              FROM (select 
                        id, code, value
                        from @Table1
                    UNION ALL
                    select
                        id, code, value
                        from @Table2
                   ) a
                  INNER JOIN (SELECT
                                  dt.id, MAX(dt.value) as MaxValue, SUM(dt.value) AS SumValue
                                  from (select 
                                            id, code, value
                                            from @Table1
                                        UNION ALL
                                        select
                                            id, code, value
                                            from @Table2
                                       ) dt
                                  group by dt.id
                             ) m ON a.id=m.id AND a.value=m.MaxValue
              GROUP BY a.id,a.Code,m.SumValue
         ) s
    ORDER BY s.id

答案 1 :(得分:1)

select id, code, sum(value) as value
from 
(
select id, code, value
from yyy
UNION
select id, code, value
from zzz
) aaa
group by id, code
order by sum(value)

或从分组中删除ID:

select code, sum(value) as value
from 
(
select id, code, value
from yyy
UNION
select id, code, value
from zzz
) aaa
group by code
order by sum(value)