varios valores unir una tablas tabla siguiente registros registro mismo misma diferente consultas concatenar con comparar columna campo sql distinct union

sql - unir - Seleccione valores distintos de varias columnas en la misma tabla



unir dos tablas sql server (3)

Estoy tratando de construir una sola instrucción SQL que devuelva valores únicos, no nulos de varias columnas, todas ubicadas en la misma tabla.

SELECT distinct tbl_data.code_1 FROM tbl_data WHERE tbl_data.code_1 is not null UNION SELECT tbl_data.code_2 FROM tbl_data WHERE tbl_data.code_2 is not null;

Por ejemplo, tbl_data es como sigue:

id code_1 code_2 --- -------- ---------- 1 AB BC 2 BC 3 DE EF 4 BC

Para la tabla anterior, la consulta SQL debe devolver todos los valores no nulos únicos de las dos columnas, a saber: AB, BC, DE, EF.

Soy bastante nuevo en SQL. Mi declaración anterior funciona, pero ¿hay una forma más limpia de escribir esta declaración SQL, ya que las columnas son de la misma tabla?


Es mejor incluir código en su pregunta, en lugar de datos de texto ambiguos, para que todos trabajemos con los mismos datos. Aquí está el esquema de muestra y los datos que he asumido:

CREATE TABLE tbl_data ( id INT NOT NULL, code_1 CHAR(2), code_2 CHAR(2) ); INSERT INTO tbl_data ( id, code_1, code_2 ) VALUES (1, ''AB'', ''BC''), (2, ''BC'', NULL), (3, ''DE'', ''EF''), (4, NULL, ''BC'');

Como comentó Blorgbeard , la cláusula DISTINCT en su solución no es necesaria porque el operador de UNION elimina filas duplicadas. Hay un operador UNION ALL que no elimina los duplicados, pero no es apropiado aquí.

Reescribir su consulta sin la cláusula DISTINCT es una buena solución para este problema:

SELECT code_1 FROM tbl_data WHERE code_1 IS NOT NULL UNION SELECT code_2 FROM tbl_data WHERE code_2 IS NOT NULL;

No importa que las dos columnas estén en la misma tabla. La solución sería la misma incluso si las columnas estuvieran en tablas diferentes.

Si no le gusta la redundancia de especificar la misma cláusula de filtro dos veces, puede encapsular la consulta de unión en una tabla virtual antes de filtrar eso:

SELECT code FROM ( SELECT code_1 FROM tbl_data UNION SELECT code_2 FROM tbl_data ) AS DistinctCodes (code) WHERE code IS NOT NULL;

Encuentro la sintaxis del segundo más fea, pero lógicamente es más nítida. ¿Pero cuál se desempeña mejor?

sqlfiddle un sqlfiddle que demuestra que el optimizador de consultas de SQL Server 2005 produce el mismo plan de ejecución para las dos consultas diferentes:

Si SQL Server genera el mismo plan de ejecución para dos consultas, entonces son prácticamente equivalentes lógicamente.

Compare lo anterior con el plan de ejecución para la consulta en su pregunta:

La cláusula DISTINCT hace que SQL Server 2005 realice una operación de ordenación redundante, ya que el optimizador de consultas no sabe que cualquier duplicado filtrado por DISTINCT en la primera consulta sería filtrado por UNION más tarde.

Esta consulta es lógicamente equivalente a las otras dos, pero la operación redundante la hace menos eficiente. En un conjunto de datos grande, esperaría que su consulta tardara más tiempo en devolver un conjunto de resultados que los dos aquí. No tomes mi palabra por ello; ¡Experimenta en tu propio entorno para estar seguro!


Intenta algo como SubQuery :

SELECT derivedtable.NewColumn FROM ( SELECT code_1 as NewColumn FROM tbl_data UNION SELECT code_2 as NewColumn FROM tbl_data ) derivedtable WHERE derivedtable.NewColumn IS NOT NULL

La UNION ya devuelve valores DISTINCT de la consulta combinada.


Intente esto si tiene más de dos columnas CREAR TABLA #temptable (Nombre1 VARCHAR (25), Nombre2 VARCHAR (25))

INSERTAR EN #temptable (Nombre1, Nombre2) VALORES (''JON'', ''Harry''), (''JON'', ''JON''), (''Sam'', ''harry'')

SELECCIONE t.Nombre1 + '','' + t.Nombre2 Nombres EN #t DESDE #temptable COMO SELECCIONAR DISTINTO ss.value DESDE #t COMO t CROSS APPLY STRING_SPLIT (T.Names, '','') AS s