2010-03-29 8 views
1

J'ai une base de données volumineuse et je compile un rapport des données. J'ai agrégé et additionné les données de plusieurs tables pour obtenir deux tableaux qui ressemblent à ce qui suit.Choisir la ligne (du groupe) avec la valeur maximale dans une base de données SQL Server

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 

J'ai besoin d'obtenir une liste d'ID, avec le code (tiré des deux tables) avec la plus grande valeur.

13 | AC 
14 | AA 
15 | AB 

Il existe 4 à 6 000 enregistrements et il n'est pas possible de modifier les tables d'origine. Je ne m'inquiète pas trop de la performance car je n'ai besoin de la faire fonctionner que quelques fois par an. Laissez-moi voir si je peux expliquer un peu plus clairement, imaginez l'ID est l'ID du client, le code est de qui ils ont commandé et la valeur est combien ils ont dépensé là. J'ai besoin d'une liste de tous les identifiants clients et du magasin où le client a dépensé le plus d'argent (et s'ils ont dépensé la même chose dans deux magasins différents, mettez une valeur comme 'ZZ' pour le nom du magasin) .

Répondre

2

essayez ceci:

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 

SORTIE:

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

(3 row(s) affected) 

Je ne sais pas ce que vous recherchez ? c'est le code MAX par id qui additionne la valeur. si ce n'est pas ce que vous recherchez s'il vous plaît préciser i nLes question plus clairement

EDIT après modification de l'OP, utilisant les mêmes tables que le code de ci-dessus:

;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 

SORTIE:

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

(3 row(s) affected) 

OP ne dit pas la version de SQL Server, donc voici une version antérieure à SQL Server 2005 qui n'utilise pas de CTE, a la même sortie que la version CTE ci-dessus:

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

ou cet ID retrait du groupement:

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

vous n'avez pas dit si vous vouliez les x premières lignes, donc je les ai juste mises dans l'ordre, avec une entrée par paire id/code. Vous voudrez peut-être supprimer le groupe par identifiant et simplement faire du code. – BlackICE

Questions connexes