2010-08-16 20 views
7

Ho una domanda che è la selezione di un gruppo di campi relativi al nome e indirizzo dei clienti, ma si riduce a:Perché "SELECT DISTINCT a, b FROM ..." restituisce meno record di "SELECT DISTINCT A + '|' + B DA ... "?

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

che restituisce un gruppo di record (10.986.590). Se si sostituisce le virgole nella select-list per formattare come una stringa concatenata tubi separati:

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

E 'il ritorno di 248 più record. Mi sono rassicurato sul fatto che non ci sono tubi in nessuno dei campi che potrebbero rovinare la fedeltà del set restituito. Cosa sta succedendo qui?

+0

Potresti vedere cosa ottieni con 'SELEZIONA a, b, c ... DA ... GRUPPO A a, b, c ...' e modificalo nella tua domanda? (come 'DISTINCT' è tecnicamente un (molto conveniente) hack) – AakashM

+0

Aggiungete anche count (*) alle query e vediamo cosa fornisce – Mark

+2

Mi aspetterei che la query utilizzi la concatenazione per restituire ** un numero inferiore di record **, poiché se qualcuno di i valori sono 'nulli' otterrai un risultato' nullo'. – RedFilter

risposta

10

Gli spazi finali potrebbero causare questo. Per confronti tra stringhe questi vengono ignorati.

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

Neat. Ho eseguito il codice abbreviato che hai postato per vedere da solo che avevi ragione e ora sto testando le due query con tutti i campi racchiusi in ltrim (rtrim()). Questo dovrebbe eliminare questo problema, giusto? – clweeks

+0

E dovrebbe gestire anche i null. – HLGEM

+0

@clweeks - Queste colonne sono annullabili? Se è così, dovrai ricordarti di gestire i null con COALESCE o qualcosa del genere. (NB: se questo è solo un task non programmabile, è possibile impostare 'SET CONCAT_NULL_YIELDS_NULL OFF' ma non qualcosa per il codice di produzione!) –

2

La realtà non sono eventuali scenari che posso pensare che si otterrebbe PIÙ record, solo in meno. Semplificherei la query selezionando solo + '|', quindi aggiungo più colonne man mano che procedi.

Problemi correlati