Es mejor incluir el código de su pregunta, en lugar de datos de texto ambiguos, para que todos trabajemos con los mismos datos. Aquí está el esquema de ejemplo y 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 Blorgbeard comentó, la cláusula DISTINCT
en su solución no es necesario porque el operador UNION
elimina filas duplicadas. Hay un operador UNION ALL
que no elimina los duplicados, pero no es apropiado aquí.
Reescritura de la consulta sin la cláusula DISTINCT
es una buena solución a 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 mesa. La solución sería la misma incluso si las columnas estuvieran en tablas diferentes.
Si no te gusta la redundancia de especificar la misma cláusula de filtro dos veces, se puede encapsular la consulta de unión en una tabla virtual antes de filtrar que:
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 de la segunda más fea , pero es lógicamente más limpio. ¿Pero cuál se comporta mejor?
he creado un sqlfiddle que demuestra que el optimizador de consultas de SQL Server 2005 produce el mismo plan de ejecución de las dos consultas diferentes:
Si SQL Server genera el mismo plan de ejecución de dos consultas, entonces son prácticamente tan bien como lógicamente equivalentes.
Compare lo anterior con el plan de ejecución de la consulta en su pregunta:
El DISTINCT
cláusula hace que SQL Server 2005 realizar una operación de tipo redundante, ya que el optimizador de consultas no sabe que los duplicados filtrado por el DISTINCT
en la primera consulta sería filtrado por el UNION
más tarde de todos modos.
Esta consulta es lógicamente equivalente a las otras dos, pero la operación redundante la hace menos eficiente. En un gran conjunto de datos, esperaría que tu consulta tardara más en devolver un conjunto de resultados que los dos aquí. No tome mi palabra para eso; ¡Experimenta en tu propio entorno para estar seguro!
Esa estructura de tabla me da la sensación de que su base de datos no está normalizada ... – gdoron
No necesita 'distinct' en la primera consulta -' union' hará eso por usted. – Blorgbeard
@gdoron: Los códigos corresponden a varias designaciones, que de hecho pueden repetirse, es decir, un registro particular puede tener BC y BC para los códigos 1 y 2. La designación del código 1 contra 2 también es significativa. Hay una tercera tabla de búsqueda de tabla para varios códigos. No es el mejor, pero eso es a lo que me refiero. – regulus