Devuelve todas las combinaciones posibles de valores en columnas en SQL


¿Cómo devuelvo una lista de todas las combinaciones de valores en 2 columnas para que sean filas nuevas en T-SQL?

Por ejemplo

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

Y convertir esto en todas las combinaciones:

1     2
1     4
1     5
2     4
2     5
4     5
Author: ItamarG3, 2010-12-07

8 answers

Asumiendo al menos SQL 2005 para el 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
 31
Author: Joe Stefanelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-07 16:14:25

Podría unir la tabla cartesiana a sí misma, lo que devolvería todas las combinaciones de ambas columnas.

select 
    distinct
    t1.Col1,
    t2.Col2
from 
    MyTable t1,
    MyTable t2
 27
Author: Bob Black,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-07 16:18:59

Puedes hacer una unión cruzada...

SELECT a.Col1, b.Col2
FROM MyTable a
CROSS JOIN MyTable b
 9
Author: JNK,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-07 16:09:56

Estaba buscando algo que hiciera esto usando solo el SQL disponible para Microsoft Access 2016. Terminé averiguando algo que otros podrían encontrar útil. Este código utiliza CROSS JOIN, así que descubrí que es necesario dividir las dos columnas en dos tablas separadas (cada una con una columna). La sentencia AND obliga a una columna a ser menor que la otra, eliminando así cualquier tipo de ocurrencias repetitivas de 1-2, 2-1.

SELECT DISTINCT Table1.Column1, Table2.Column1
FROM Table1, Table2
WHERE Table1.Column1 <> Table2.Column1
AND Table2.Column1 < Table1.Column1;
 5
Author: Josh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-31 18:28:48

Creo que esto ha sido demasiado complicado!

Solo:

SELECT distinct Col1, Col2

FROM MyTable

Para obtener todas las combinaciones posibles..

 2
Author: Casual user,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-28 11:31:50

Esto usa 2 cte, el primero simplemente reproduce su tabla de entrada, el segundo convierte ambas columnas en una sola columna. La final select crossjoin's este conjunto a sí mismo para producir la salida requerida

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
 1
Author: Jamiec,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-07 16:23:27

Encuentro una unión interna más intuitiva porque la uso con más frecuencia que una unión cruzada:

;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
Author: Tim Hauser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-06-25 21:58:06

Haciendo que Joe responda más fácil

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

Verifique su cantidad de combinaciones (No de filas) http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php

 0
Author: Faheem Ahmad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-11 22:27:28