开发者

choosing row (from group) with max value in a SQL Server Database

开发者 https://www.devze.com 2022-12-24 07:08 出处:网络
I have a large database and am putting together a report of the data. I have aggregated and summed the data from many tables to get two tables that look like the following.

I have a large database and am putting together a report of the data. I have aggregated and summed the data from many tables to get two tables that look like the following.

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开发者_StackOverflow中文版  | 0.5
15 |  AB  | 0.5            15 |  AB  | 3.0
15 |  AD  | 1.5            15 |  AA  | 1.0

I need to get a list of id's, with the code (sumed from both tables) with the largest value.

13 |  AC
14 |  AA
15 |  AB

There are 4-6 thousand records and it is not possible to change the original tables. I'm not too worried about performance as I only need to run it a few times a year.

edit: Let me see if I can explain a bit more clearly, imagine the id is the customer id, the code is who they ordered from and the value is how much they spent there.

I need a list of the all the customer id's and the store that customer spent the most money at (and if they spent the same at two different stores, put a value such as 'ZZ' in for the store name).


try this:

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

OUTPUT:

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

(3 row(s) affected)

I'm not sure what you are after? this is the MAX code per id summing the value. if this is not what you are after please specify i nthe question more clearly

EDIT after OP's edit, using same tables as code from above:

;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

OUTPUT:

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

(3 row(s) affected)

OP doesn't say the version of SQL Server, so here is a pre SQL Server 2005 version that does not use CTEs, has same output as the CTE version above:

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


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)

or this removing id from the grouping:

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)
0

精彩评论

暂无评论...
验证码 换一张
取 消