2009-06-26 10 views
3

J'essaie de trouver un moyen de combiner des lignes dans une table en fonction de la plus longue chaîne de n'importe quelle ligne basée sur une clé de ligneT-SQL Grouper des lignes à partir des colonnes de longueur MAX dans différentes lignes (?)

exemple

CREATE TABLE test1 
    (akey int not null , 
    text1 varchar(50) NULL, 
    text2 varchar(50) NULL, 
    text3 varchar(50) NULL ) 


INSERT INTO test1 VALUES (1,'Winchester Road','crawley',NULL) 
INSERT INTO test1 VALUES (1,'Winchester Rd','crawley','P21869') 
INSERT INTO test1 VALUES (1,'Winchester Road','crawley estate','P21869') 
INSERT INTO test1 VALUES (1,'Winchester Rd','crawley','P21869A') 
INSERT INTO test1 VALUES (2,'','birmingham','P53342B') 
INSERT INTO test1 VALUES (2,'Smith Close','birmingham North East','P53342') 
INSERT INTO test1 VALUES (2,'Smith Cl.',NULL,'P53342B') 
INSERT INTO test1 VALUES (2,'Smith Close','birmingham North','P53342') 

avec ces lignes je rechercherais le résultat de:

1 Winchester Road, crawley estate, P21869A 
2 Smith Close, birmingham North East, P53342B 

EDIT: les résultats ci-dessus doivent être dans une table Rathe r que juste une chaîne séparée par des virgules

comme vous pouvez le voir dans le résultat, la sortie doit être la colonne de texte la plus longue dans la plage du champ «akey».

J'essaie de trouver une solution qui n'implique pas beaucoup de sous-requêtes sur chaque colonne, la table réelle a 32 colonnes et plus de 13 millions de lignes.

la raison pour laquelle je fais est de créer une table assaini a les meilleurs résultats dans chaque colonne pour un seul ID par ligne

c'est mon premier post, alors laissez-moi savoir si vous avez besoin plus d'info, et je suis heureux d'entendre parler des meilleures pratiques sur la publication que j'ai cassé!

merci

Ben.

+0

Merci pour les scripts de table! – Quassnoi

+0

de rien! J'ai pensé que si je veux une réponse, je dois rendre la tâche facile pour les gens de faire leurs propres tests. –

Répondre

2
SELECT A.akey, 
    (
     SELECT TOP 1 T1.text1 
     FROM test1 T1 
     WHERE T1.akey=A.akey AND LEN(T1.TEXT1) = MAX(LEN(A.text1)) 
    ) AS TEXT1, 
    (
     SELECT TOP 1 T2.text2 
     FROM test1 T2 
     WHERE T2.akey=A.akey AND LEN(T2.TEXT2) = MAX(LEN(A.text2)) 
    ) AS TEXT2, 
    (
     SELECT TOP 1 T3.text3 
     FROM test1 T3 
     WHERE T3.akey=A.akey AND LEN(T3.TEXT3) = MAX(LEN(A.text3)) 
    ) AS TEXT3 
FROM TEST1 AS A 
GROUP BY A.akey 

Je viens de réaliser que vous aviez 32 colonnes. Je ne vois pas un bon moyen de le faire, à moins que UNPIVOT ne vous permette de créer des lignes séparées (akey, textn) pour chaque colonne text *.

Edit: Je ne peux pas avoir une chance de terminer aujourd'hui, mais UNPIVOT semble utile:

; 
WITH COLUMNS AS 
(
    SELECT akey, [Column], ColumnValue 
    FROM 
     (
      SELECT X.Akey, X.Text1, X.Text2, X.Text3 
      FROM test1 X 
     ) AS p 
    UNPIVOT (ColumnValue FOR [Column] IN (Text1, Text2, Text3)) 
    AS UNPVT 
) 
SELECT * 
FROM COLUMNS 
ORDER BY akey,[Column], LEN(ColumnValue) 
+0

que peu pivoter semble prommising, je n'ai pas utilisé pivot/unpivot beaucoup. Je suppose que nous devons ensuite PIVOT les données une fois que nous avons sélectionné les plus longues chaînes de caractères? –

+0

Oui, je pense que vous auriez besoin de PIVOT. –

1

Cela semble vraiment laid, mais au moins fonctionne (sur SQL2K) et n'a pas besoin de sous-requêtes :

select test1.akey, A.text1, B.text2, C.text3 
from test1 
inner join test1 A on A.akey = test1.akey 
inner join test1 B on B.akey = test1.akey 
inner join test1 C on C.akey = test1.akey 
group by test1.akey, A.text1, B.text2, C.text3 
having len(a.text1) = max(len(test1.text1)) 
    and len(B.text2) = max(len(test1.text2)) 
    and len(C.text3) = max(len(test1.text3)) 
order by test1.akey 

Je dois admettre qu'il a besoin d'une jointure interne pour chaque colonne et je me demande comment cela pourrait avoir un impact sur la table d'enregistrement 32 colonnes x 13millions ... J'essaie à la fois cette approche et celle basée un sous-requêtes et regardé les exécutions pla ns: Je serais curieux de savoir

+0

merci, cela fonctionne très bien pour la table d'exemple, mais je suis réticent à faire ~ 32 scans de table sur des lignes de 13m. –

+0

.. Je vais essayer les deux méthodes pour voir ce qui fonctionne mieux, à la fois pour notre curiosité. –

+1

les résultats sont la méthode de sous-requête par John est massivement plus efficace selon les plans d'exécution. –

Questions connexes