2012-01-03 22 views
16

Devo controllare se una colonna NON è NULL nella mia istruzione SQL.Verifica se una colonna NON è NULL

mia query SQL:

select column_a, column_b, column_c, column_d, column_x 
from myTable 

Ho un sacco di colonne nel mio select. Così ho un problema di prestazioni, se vorrei fare le seguenti:

select column_a, column_b, column_c, column_d, column_x 
from myTable 
where column_a is not null or column_b is not null or column_c is not null 
or column_x is not null 

C'è un altro (migliore) modo per verificare se ci sono delle colonne che non sono NULL?

+1

Perché si dice che si tratta di un problema di prestazioni? La maggior parte di questi valori di colonna è in realtà 'NULL', pertanto esegue la scansione di righe non necessarie? Come sei arrivato a questa conclusione? –

+0

È possibile inserire prima le colonne contenenti la quantità minima di NULL? Che ne dici di un indice su tutte le colonne? –

+0

Vuoi sapere se una colonna ha un valore NULL (come indicato nel titolo della domanda e nel corpo della domanda), o se nessuna colonna ** non ** ha un valore NULL (come scritto nella tua query SQL). Due domande completamente diverse. – RedFilter

risposta

22

Per questo è possibile utilizzare COALESCE. COALESCE restituisce il primo valore non nullo, se presente. Questo probabilmente non funzionerà meglio, ma è molto più leggibile.

Esempio:

where coalesce(column_a, column_b, column_c, column_x) is not null 

seconda della cardinalità dei dati, si può essere in grado di aggiungere indici per aiutare le prestazioni.

Un'altra possibilità è utilizzare la colonna calcolata persistente che indica se tutte e quattro le colonne sono NULL o no.

+1

Si * potrebbe * ma non si saprebbe quale colonna è nullo (eccetto che un risultato nullo significa che sono tutti). Se l'OP vuole confermare ogni colonna è nulla, allora un COALESCE funzionerebbe bene. Tuttavia, non sarebbe un modo conciso per rilevare se * any * column è nullo. –

+3

@Brad: l'OP sta selezionando dove una colonna è ** non ** null. 'COALESCE' funziona perfettamente per questo e non fornisce più o meno informazioni rispetto alla query originale. – RedFilter

+1

Sto capendo la domanda come "come faccio a sapere se una di queste colonne è nulla". Un COALESCE non ti dirà se una singola colonna è nulla, solo che almeno una non è o tutte sono. Quindi finché la prima colonna non è nulla, stai davvero ignorando un test nei prossimi tre. (Allo stesso modo per i primi due rispetto agli ultimi due, e così via). Forse sto fraintendendo la domanda. –

2

Un modo per attaccare questo potrebbe essere quello di aggiungere una colonna di bit aggiuntiva che tenga traccia di eventuali valori o meno.

Pro

  • può essere implementato con i trigger in modo non c'è bisogno di cambiare il resto del codice
  • Non richiede la scansione delle altre colonne
  • quella colonna possono essere indicizzati

Contro

  • I suoi dati sarebbero stati de-normalizzato
  • Più complicato/più manutenzione
  • Più spazio di archiviazione per la colonna aggiuntiva

Sia i pro superano i contro dipendono da quanto di una performance colpire stai prendendo guardando le altre colonne. Profilalo prima di impegnarti!

+0

L'indice probabilmente non verrebbe utilizzato a meno che non coprisse 'column_a, column_b, column_c, column_d, column_x' a causa del costo delle ricerche a meno che non si trovassero in una situazione insolita in cui era' NULL' per tutte le colonne per la stragrande maggioranza di anche le righe potrebbero utilizzare direttamente un indice filtrato o una vista indicizzata con il criterio 'NOT NULL'. –

+0

Ciao RQDQ, grazie per la tua risposta. Presumo, che è un grande sovraccarico, se faccio una colonna separata per questo valore. Forse nella query sql con un tavolo temperato? – bitsmuggler

2

Mi piace generalmente il suggerimento di RedFilter di COALESCE, ma un'altra soluzione potrebbe essere l'uso della funzione CHECKSUM(). Naturalmente, il valore del checksum per tutti i valori NULL dipende dalle colonne e dai tipi di dati, pertanto è necessario prima eseguire una query per ottenere tale valore. Qualcosa di simile:

select CHECKSUM(*) AS [All_NULL_Value] 
from myTable 
where column_a is null 
AND column_b is null 
AND column_c is null 
AND column_d is null 
AND column_x is null 

allora si può fare questo:

select column_a, column_b, column_c, column_d, column_x 
from myTable 
where CHECKSUM(*) <> {All_NULL_Value_obtained_above} 

io non sono sicuro se questo comporta meglio o peggio di dell'idea COALESCE, ma potrebbe essere la pena di provare.

0

Risposta accettata 5 anni fa, ma, come ha detto Brad, in base al titolo della domanda la coalesce è un approccio sbagliato. Se in alcuni casi è davvero necessario controllare o QUALSIASI parametro è nullo, è possibile utilizzare questo:

where convert(binary, column_a) + convert(binary, column_b) + convert(binary, column_c), + convert(binary, column_k) is null 
+0

"la coalesce è un approccio sbagliato" Perché? –

Problemi correlati