Seleziona distinti da più campi usando sql

Ho 5 colonne corrispondenti alle risposte in un database del gioco a quiz – a destra, wrong1, wrong2, wrong3, wrong4

Voglio restituire tutte le risposte possibili senza duplicati. Speravo di farlo senza usare un tavolo temporaneo. È ansible utilizzare qualcosa di simile a questo ?:

select c1, c2, count(*) from t group by c1, c2 

Ma questo restituisce 3 colonne. Vorrei una colonna di risposte distinte.

Grazie per il tuo tempo

Questo dovrebbe darti tutti i valori distinti dalla tabella. Presumo che tu voglia aggiungere delle clausole dove selezionare solo per una particolare domanda. Tuttavia, questa soluzione richiede 5 sottoquery e può essere lenta se la tabella è enorme.

 SELECT DISTINCT(ans) FROM ( SELECT right AS ans FROM answers UNION SELECT wrong1 AS ans FROM answers UNION SELECT wrong2 AS ans FROM answers UNION SELECT wrong3 AS ans FROM answers UNION SELECT wrong4 AS ans FROM answers ) AS Temp 
 SELECT DISTINCT(ans) FROM ( SELECT right AS ans FROM answers UNION SELECT wrong1 AS ans FROM answers UNION SELECT wrong2 AS ans FROM answers UNION SELECT wrong3 AS ans FROM answers UNION SELECT wrong4 AS ans FROM answers ) AS Temp 

Il DISTINCT è superfluo, in quanto l’UNION non restituirà righe identiche per tutte le colonne. (Quando vuoi duplicati, o se sai che non esistono duplicati, usa UNION ALL per prestazioni più veloci)

Questo ti darà una lista unica contenente tutte le risposte. Avrai comunque dei duplicati se hai più copie della stessa risposta all’interno di una singola colonna.

Questo non dovrebbe essere il caso se usi UNION, solo se usi UNION ALL

 SELECT [value] INTO #TEMP FROM ( SELECT [value] = 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 1 ) AS X (4 row(s) affected) SELECT [value] FROM #TEMP value ----------- 1 2 3 1 (4 row(s) affected) SELECT [value] FROM #TEMP UNION SELECT [value] FROM #TEMP value ----------- 1 2 3 (3 row(s) affected) 

Ho fornito una risposta sopra .

Tuttavia ho immaginato un modo molto migliore per farlo usando UNPIVOT.

 SELECT DISTINCT(ans) FROM ( SELECT [Name], ANS FROM ( SELECT right, wrong1, wrong2, wrong3, wrong4 FROM answers ) AS PVT UNPIVOT (ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT ) AS OUTPUT; 

È ansible fornire qualsiasi clausola WHERE nella sottoquery interna:

 SELECT DISTINCT(ans) FROM ( SELECT [Name], ANS FROM ( SELECT right, wrong1, wrong2, wrong3, wrong4 FROM answers WHERE (...) ) AS PVT UNPIVOT (ans FOR [Name] IN (right, wrong1, wrong2, wrong3, wrong4)) AS UNPVT ) AS OUTPUT; 

Bene, puoi usare UNION ed eseguire 5 istruzioni select, una per ogni colonna nella tua tabella. Sarebbe simile a questo:

 SELECT right FROM answers UNION SELECT wrong1 FROM answers UNION SELECT wrong2 FROM answers UNION SELECT wrong3 FROM answers UNION SELECT wrong4 FROM answers 

Questo ti darà una lista unica contenente tutte le risposte. Avrai comunque dei duplicati se hai più copie della stessa risposta all’interno di una singola colonna.

Le colonne di “right, wrong1, wrong2, wrong3, wrong4” significano che hai un database mal progettato. In generale, un suffisso di numero o lettera sul nome di una colonna dovrebbe essere una bandiera rossa per ripensare al problema.

Come hai osservato, il tuo progetto richiedeva di hackerarti per ottenere una soluzione a un tipico problema di riduzione dei dati.

Questo è quello che volevi?

select distinct c1 from t

In MySQL e MS SQL :

 SELECT CASE WHEN which = 1 THEN c1 WHEN which = 2 THEN c2 WHEN which = 3 THEN c3 WHEN which = 4 THEN c4 WHEN which = 5 THEN c5 END AS answer, which FROM mytable, ( SELECT 1 AS which UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 ) w 

Per Oracle , aggiungi FROM DUAL a ciascuno dei numeri selezionati.

Questa è la risposta esatta.

 SELECT (ans) FROM ( SELECT correct AS ans FROM tGeoQuiz UNION SELECT wrong1 AS ans FROM tGeoQuiz UNION SELECT wrong2 AS ans FROM tGeoQuiz UNION SELECT wrong3 AS ans FROM tGeoQuiz UNION SELECT wrong4 AS ans FROM tGeoQuiz ) AS Temp