2010-06-24 16 views
14

Come posso eseguire una query MySQL che seleziona tutto ciò che non è nullo? Sarebbe qualcosa comeWHERE all IS NOT NULL

SELECT * FROM schedule WHERE ((all)) IS NOT NULL 

Devo solo rimuovere tutto e andare ..?

SELECT * FROM schedule WHERE IS NOT NULL 
+2

Sarebbe utile se si aggiungessero dati di esempio e risultati attesi alla domanda – Naktibalda

+1

Non penso che farebbe alcuna differenza per la risposta. – Sam

+5

Certo che ... Non ci hai dato informazioni su cosa non dovrebbe essere nullo ... Un esempio potrebbe mostrarci cosa ti aspetti! – Fred

risposta

18

Dovrai dichiarare esplicitamente la condizione su ogni colonna, quindi ad es.

SELECT * 
FROM schedule 
WHERE id IS NOT NULL 
    AND foo IS NOT NULL 
    AND bar IS NOT NULL; -- and so on.. 
+0

Quindi non è possibile ottenere solo tutto ciò che non è nullo ...Dannazione. – Sam

+0

Credo che ci sia un modo, per favore dai un'occhiata alla mia risposta. – Anax

+0

Anax mi ha dato un'idea quindi sono andato a cercare. In fondo ho aggiunto un modo per farlo in modo da avere un'istruzione select in modo da non dover iterare attraverso molte colonne. Utile se si dispone di una tabella dinamica in cui non è possibile aggiornare l'istruzione select – Sam

5

Dipende da cosa si intende esattamente per "tutto ciò che non è nullo":

  • tutte le colonne non deve essere null

    select * from schedule where col1 is not null AND col2 is not null AND ..

  • almeno una colonna dovrebbe essere non-null

    select * from schedule where col1 is not null OR col 2 is not null OR ..

Almeno questo è come si dovrebbe fare in "sql generale". Non so se MySql abbia una sintassi speciale per questo.

10

È possibile concatenare i campi al fine di scrivere solo dove-condizione:

SELECT * 
    FROM SCHEDULE 
WHERE ID || FOO || BAR IS NOT NULL; 
+3

È una bella stenografia, ma consigliabile; questo non funzionerà necessariamente in tutti i database. Ad esempio, le versioni successive di Postgres lo accetteranno solo se la prima colonna è di tipo testuale; come varchar, char o testo. Potrei anche immaginare determinati database per richiedere il cast per ogni colonna che non è di questo tipo. – pyrocumulus

+3

Se si dispone di campi di testo lunghi, la concatenazione è un'operazione costosa. Inoltre, la lunghezza del risultato potrebbe essere troppo lunga, creando un errore. – Kobi

+2

Se sono presenti campi di testo lunghi, è possibile utilizzare: WHERE ID || SUBSTR (FOO, 1,1) || SUBSTR (FOO, 1,1) NON È NULL; In questo modo, si estrae solo il primo carattere di ogni campo di testo lungo. – UltraCommit

0

Se si utilizza un altro linguaggio di programmazione in combinazione con SQL, si potrebbe accelerare questo processo da loop attraverso un elenco di colonne nomi e utilizzando un parametro per fare il controllo se non nullo, piuttosto che avere a tutti loro digitare singolarmente ad esempio

**code SQL** 

Select * 
FROM Schedule 
WHERE @ColumnName IS NOT NULL 

**code c#** 

for(int i =0; i<parameterArray[].length; i++) 
{ 
command.Parameters.Add(new SqlParameter("ColumnName", parameterArray[i])); 
command.Execute(); 
} 

io suggerirei di usare le transazioni in modo da poter fare quanto sopra in un lotto dopo il ciclo è eseguito attraverso .

3

È necessario ottenere un elenco delle colonne della tabella, osservando il database information_schema.

Supponiamo che il database sia chiamato mydata e che la tabella in questione sia denominata mytable. È possibile ottenere l'elenco di colonne nullable della tabella emettendo la seguente dichiarazione:

SELECT `COLUMN_NAME` 
FROM `information_schema`.`COLUMNS` 
WHERE `TABLE_SCHEMA` = 'mydata' 
    AND `TABLE_NAME` = 'mytable' 
    AND `IS_NULLABLE` = 'YES' 

nostra query finale sarà simile a questa:

SELECT * FROM `mydata`.`mytable` 
WHERE CONCAT(<list of columns>) IS NOT NULL 

Tutto quello che manca ora è la lista delle colonne nullable, separato da virgola.Abbiamo intenzione di utilizzare la funzione GROUP_CONCAT per produrre la dichiarazione finale, che verrà eseguito in questo modo:

SET @query = CONCAT(
    'SELECT * FROM `mydata`.`mytable` WHERE CONCAT(', 
    (SELECT GROUP_CONCAT(COLUMN_NAME) 
     FROM `information_schema`.`COLUMNS` 
     WHERE `TABLE_SCHEMA` = 'mydata' AND 
     `TABLE_NAME` = 'mytable' 
     AND `IS_NULLABLE` = 'YES'), 
    ') IS NOT NULL'); 

PREPARE stmt_name FROM @query; 

EXECUTE stmt_name; 

Riferimenti:

http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

3

ho appena guardato al tuo linked question e concorda con la risposta di Guffa che devi normalizzare il tuo database.

Linked Question Image

L'aspetto di cui sopra più simile a un foglio di calcolo, allora qualcosa che appartiene a un RDBMS.

Per rispondere alle vostre preoccupazioni su come questo sia visualizzato nel modo desiderato. È possibile scrivere una query pivot e inserirla in una vista per simulare la struttura della tabella corrente e utilizzarla per la query di visualizzazione.

Ciò eviterà la necessità di qualche orribile clausola WHERE di 24 colonne ogni volta che si desidera cercare dati o scoprire se è NULL come in questa domanda.

-2

avrei non fare questo, ma to replace someone else's horrible idea., soprattutto non farlo - questo è ciò che hanno suggerito:

SELECT * 
    FROM SCHEDULE 
WHERE ID || FOO || BAR IS NOT NULL; 

non fare questo o, ma almeno non è così male ...

SELECT * 
    FROM SCHEDULE 
WHERE coalesce(ID, FOO, BAR) IS NOT NULL; 

Questo almeno funziona su altre versioni di SQL, e alcuni compilatori si espanderà ad una serie di IS NOT NULL.

Just do what the accepted answer says

0

utilizzare XML in modo che non c'è bisogno di scorrere tutte le colonne:

--Your Source Table 
CREATE TABLE [dbo].[schedule](
    [id] [nchar](10) NULL, 
    [col1] [nchar](10) NULL, 
    [col2] [nchar](10) NULL, 
    [col3] [nchar](10) NULL 
) ON [PRIMARY] 

--I know my result should show items NOT NULL, like id:2,col1,val:'a' 
    INSERT INTO [schedule](id,col1,col2,col3) 
    values 
    (1,null,null,null), 
    (2,'a',null,null), 
    (3,null,'b',null), 
    (4,null,null,null), 
    (5,null,null,'c') 

--temp placeholder table 
CREATE TABLE #tempsch (id VARCHAR(max) not null, schColumns XML) 

--Load temp table with XML version of your table 
INSERT INTO #tempsch (id, schColumns) 
     SELECT s.id, 
      ( SELECT * 
       FROM [schedule] AS x 
       WHERE x.id = s.id 
       FOR XML PATH('bar'), TYPE, ROOT('foo') 
      ) AS xml_format_string 
     FROM [schedule] AS s 


--This select should return all values Where all is NOT NULL 
SELECT id, 
sd.c.value('local-name(.)', 'VARCHAR(MAX)') AS elementName, 
sd.c.value('.', 'VARCHAR(MAX)') AS elementValue 
FROM #tempsch s 
CROSS APPLY schColumns.nodes('/foo/bar/*') sd(c) 
WHERE 
sd.c.value('local-name(.)', 'VARCHAR(MAX)') <> 'id' 
0

questo funziona solo con char e tipo varchar. Se si hanno altri tipi di dati, si genera un errore.

SELECT * 
    FROM SCHEDULE 
WHERE coa 

lesce(ID, FOO, BAR) IS NOT NULL; 

tipi di dati incoerenti: attesi CHAR ottenuto DATE Nota: qui FOO è di tipo data.

Problemi correlati