2010-12-07 6 views
21

Comment renvoyer une liste de toutes les combinaisons de valeurs dans 2 colonnes afin qu'elles soient nouvelles dans T-SQL?Renvoyer toutes les combinaisons possibles de valeurs sur les colonnes dans SQL

par exemple.

Col1, Col2 
---- ---- 
1  2 
1  4 
1  5 

et transformer cela en toutes les combinaisons:

1  2 
1  4 
1  5 
2  4 
2  5 
4  5 
+1

Qu'entendez-vous par 'nouvelles lignes'? Quelles sont les règles pour combiner? Est-ce que "1,1" est valide ou non? – Oded

+0

Les 3 lignes d'origine se trouvent dans une table et doivent être développées à l'aide d'une instruction select. – jaffa

Répondre

28

En supposant au moins SQL 2005 pour le CTE:

;with cteAllColumns as (
    select col1 as col 
     from YourTable 
    union 
    select col2 as col 
     from YourTable 
) 
select c1.col, c2.col 
    from cteAllColumns c1 
     cross join cteAllColumns c2 
    where c1.col < c2.col 
    order by c1.col, c2.col 
+0

Selon les commentaires dans la réponse @ BobBlack, c'est la solution acceptée car elle évite de répéter '1-2' et' 2-1' etc. (ie les résultats sont un ensemble non ordonné) – LondonRob

9

Vous pouvez faire une auto jointure croisée ...

SELECT a.Col1, b.Col2 
FROM MyTable a 
CROSS JOIN MyTable b 
+0

Pourquoi cette réponse n'est-elle pas plus populaire? Y a-t-il quelque chose qui ne va pas? –

+0

Cela nécessite 'SELECT DISTINCT' je pense. Aussi, bien que cela soit utile, il ne fait pas ce que l'OP veut, c'est-à-dire toutes les combinaisons de * deux * colonnes! – LondonRob

24

cartésienne Vous pouvez joindre la table elle-même, qui renverrait toutes les combinaisons des deux colonnes.

select 
    distinct 
    t1.Col1, 
    t2.Col2 
from 
    MyTable t1, 
    MyTable t2 
+0

Ajoutez "select distinct" et vous l'avez. –

+0

J'ai essayé mais j'ai besoin des valeurs de Col 2 dans la Col 1 pour qu'elles soient inversées. Je pensais que nonpivot pourrait aider, mais pas vraiment sûr ... – jaffa

+0

@Sir Wobin: bonne suggestion. Réponse mise à jour –

1

Il utilise 2 cte, le premier étant reproduit simplement votre table d'entrée, la seconde les deux colonnes s'en une seule colonne. cet ensemble se de la sélection finale Crossjoin pour produire la puissance requise

with t(c1,c2) 
AS 
(
    select 1,2 
    union select 1,4 
    union select 1,5 
) 
,t2(c) 
as 
(
    select c1 from t 
    union select c2 from t 
) 
select t2_1.c, t2_2.c 
from t2 t2_1 
cross join t2 t2_2 
where t2_1.c<t2_2.c 
order by t2_1.c 
0

Je trouve une jointure plus intuitive parce que je l'utilise plus souvent qu'une croix rejoindre:

;with cteAllColumns as (
select col1 as col 
    from YourTable 
union 
select col2 as col 
    from YourTable 
) 

select c1.col, c2.col 
from cteAllColumns c1 
    join cteAllColumns c2 on 1=1 
where c1.col < c2.col 
order by c1.col, c2.col 
0

Faire Joe Réponse facile

declare @t1 table (col1 varchar(5)) 
insert @t1 
    select 'A' UNION 
    select 'B' UNION 
    select 'C' 


declare @t2 table (col2 varchar(5)) 
insert @t2 
    select '1' UNION 
    select '2' UNION 
    select '3' 


;with cteAllColumns as (
    select col1 as col 
     from @t1 
    union 
    select col2 as col 
     from @t2 
) 
select c1.col, c2.col 
    from cteAllColumns c1 
     cross join cteAllColumns c2 
    where c1.col < c2.col 
    order by c1.col, c2.col 

vérifier vos combinaisons Quantité (pas de lignes) http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php

2

Je pense que cela a été trop compliqué!

Just:

SELECT distinct Col1, Col2 

FROM MyTable 

pour obtenir toutes les combinaisons possibles ..

+0

Cela a déjà 6 autres réponses, une dont a été marqué comme _Accepted_. Mis à part le fait que votre réponse n'est pas formatée, que pensez-vous qu'elle apporte à la table? – Bugs

+0

Cette requête a couru en un instant pour moi - elle a renvoyé toutes les combinaisons possibles de deux champs dans ma table. Les autres requêtes ont expiré. J'espère que cela aidera les autres, comme vous m'avez aidé à identifier mes lacunes. –

+1

Cette solution est excellente, a fonctionné comme un charme pour moi et était très simple. Ne vous sentez jamais gêné d'ajouter une solution potentiellement meilleure à une question déjà posée. – Steve

5

Je cherchais quelque chose qui ferait cela en utilisant uniquement le SQL disponible pour Microsoft Access 2016. J'ai fini par déterminer quelque chose qui d'autres peuvent trouver utile. Ce code utilise CROSS JOIN donc j'ai trouvé qu'il est nécessaire de diviser les deux colonnes en deux tables séparées (chacune avec une colonne). L'instruction AND force une colonne à être inférieure à l'autre, éliminant ainsi toutes les occurrences répétitives 1-2, 2-1.

SELECT DISTINCT Table1.Column1, Table2.Column1 
FROM Table1, Table2 
WHERE Table1.Column1 <> Table2.Column1 
AND Table2.Column1 < Table1.Column1; 
+0

Salut Josh, bienvenue à Stack Overflow! Les nouveaux utilisateurs écrivent souvent de très mauvaises réponses. Félicitations pour avoir tenté d'expliquer pourquoi votre solution pourrait être mieux adaptée à certains lecteurs. +1 pour ça! –

Questions connexes