2010-12-07 32 views
21

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

p. Ej.

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 
+1

¿Qué quieres decir con 'new rows'? ¿Cuáles son las reglas para combinar? Es '1,1 'válido o no? – Oded

+0

Las 3 filas originales están dentro de una tabla y deben expandirse utilizando una instrucción select. – jaffa

Respuesta

28

Suponiendo 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 
+0

Según los comentarios en la respuesta de @ BobBlack, esta es la solución aceptada porque evita repetir '1-2' y' 2-1' etc. (es decir, los resultados son un conjunto desordenado) – LondonRob

9

Usted puede hacer una cruz auto unirse ...

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

¿Por qué esta respuesta no es más popular? ¿Hay algo mal? –

+0

Esto necesita 'SELECT DISTINCT', creo. Además, aunque esto es útil, no hace lo que el OP quiere, ¡que son todas las combinaciones de * ambas * columnas! – LondonRob

24

Se podría cartesiano unirse a la tabla consigo misma, lo que devolvería todas las combinaciones de ambas columnas.

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

Agrega "seleccionar distinto" y lo tienes. –

+0

He intentado esto pero necesito valores de Col 2 en Col 1 para que se intercambien. Pensé que unpivot podría ayudar pero no estoy seguro ... – jaffa

+0

@Sir Wobin: buena sugerencia. Respuesta actualizada –

1

Este utiliza 2 CTE, la primera se limita a reproducir su mesa de entrada, la segunda gira ambas columnas en una sola columna. del Crossjoin de selección final de 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 
0

encuentro una combinación interna más intuitivo porque yo lo uso con más frecuencia que una combinació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

Haciendo Joe respuesta 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 

verificar sus combinaciones Cantidad (Nº de filas) http://www.calculatorsoup.com/calculators/discretemathematics/combinations.php

2

¡Creo que esto ha sido muy complicado!

Justo:

SELECT distinct Col1, Col2 

FROM MyTable 

para obtener todas las combinaciones posibles ..

+0

Esto ya tiene otras 6 respuestas, una de los cuales ha sido marcado como _Aceptado_. Además del hecho de que tu respuesta no está formateada, ¿qué más crees que traiga a la mesa? – Bugs

+0

Esta consulta se ejecutó en un instante para mí, devolvió todas las combinaciones posibles de dos campos en mi tabla. Las otras consultas agotaron el tiempo de espera. Espero que ayude a otros, como usted me ayudó a identificar mis deficiencias. –

+1

Esta solución es excelente, funcionó como un encanto para mí y fue muy simple. Nunca se sienta mal por agregar una solución potencialmente mejor a una pregunta ya respondida. – Steve

5

que estaba buscando algo que hacer esto utilizando sólo el SQL disponible para Microsoft Access 2016. Terminé averiguar algo que otros pueden encontrarle ú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 instrucción AND fuerza a que una columna sea menos que la otra, eliminando así cualquier tipo de ocurrencias 1-2, 2-1 repetitivas.

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

Hola Josh, bienvenido a Stack Overflow! Los nuevos usuarios a menudo escriben respuestas bastante malas. Felicitaciones por esforzarte en explicar por qué tu solución podría ser más adecuada para algunos lectores. +1 por eso! –

Cuestiones relacionadas