2010-08-16 17 views
7

Tengo una consulta que está seleccionando un grupo de campos relacionados con los nombres y direcciones de los clientes, sino que se reduce a:¿Por qué "SELECT DISTINCT a, b FROM ..." devuelve menos registros que "SELECT DISTINCT A + '|' + B DE ... "?

SELECT DISTINCT a, b, c, ... FROM big_dumb_flat_table 

devuelve un montón de discos (10986590). Si se sustituyen las comas en la lista de selección para formatearlo como una cadena concatenada tubería separada por:

SELECT DISTINCT a + '|' + b + '|' + c + '|' + ... FROM big_dumb_flat_table 

Es devolver 248 registros más. Me he asegurado a mí mismo que no hay tuberías en ninguno de los campos que podrían estar atornillando la fidelidad del conjunto devuelto. ¿Que está pasando aqui?

+0

¿Podría ver lo que obtiene con 'SELECT a, b, c ... FROM ... GROUP BY a, b, c ...' y edítelo en su pregunta? (como 'DISTINCT' es técnicamente un (muy conveniente) hack) – AakashM

+0

También agregue count (*) a las consultas y vea qué da eso – Mark

+2

Espero que la consulta que usa concatenación devuelva ** menos ** registros, ya que si alguno de los valores son 'null' obtendrá un resultado' null'. – RedFilter

Respuesta

10

Los espacios al final podrían causar esto. Para las comparaciones de cadenas, se ignoran.

CREATE TABLE #T 
(
a varchar(10), 
b varchar(10), 
c varchar(10) 
) 

INSERT INTO #T 
SELECT 'a ' as a, 'b' as b, 'c ' as c union all 
SELECT 'a' as a, 'b' as b, 'c ' as c 

SELECT DISTINCT a, b, c 
FROM #T /*1 result*/ 

SELECT DISTINCT a + '|' + b + '|' + c + '|' 
FROM #T /*2 results*/ 


SELECT DISTINCT LTRIM(RTRIM(a)) + '|' + LTRIM(RTRIM(b)) + '|' + 
       LTRIM(RTRIM(c)) + '|' 
FROM #T /*1 result*/ 
+0

aseado. Ejecuté el código abreviado que primero publicó para ver por mí mismo que tenía razón y ahora estoy probando las dos consultas con todos los campos envueltos en ltrim (rtrim()). Eso debería eliminar este problema, ¿verdad? – clweeks

+0

Y él debería estar manejando nulos también. – HLGEM

+0

@clweeks - ¿Estas columnas son nulables? Si es así, deberá recordar manejar Nulls con COALESCE o algo así. (NB: si se trata de una tarea única, puede hacer 'SET CONCAT_NULL_YIELDS_NULL OFF' pero no algo para el código de producción!) –

2

El realmente no son escenarios que se me ocurre que le conseguiría MÁS registros, solamente menos. Simplificaría la consulta seleccionando solo un + '|' y luego agregaría más columnas sobre la marcha.

Cuestiones relacionadas