2009-02-13 7 views
12

Ich habe 5 Spalten Antworten in einem Quiz-Spiel-Datenbank entspricht - rechts, wrong1, wrong2, wrong3, wrong4Verwendung von mehreren Feldern unterschiedliche Wählen Sie SQL

ich alle möglichen Antworten ohne Duplikate zurückgeben möchten. Ich hatte gehofft, dies ohne einen Temp-Tisch zu erreichen. Ist es möglich, etwas Ähnliches zu verwenden ?:

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

Aber das gibt 3 Spalten zurück. Ich hätte gerne eine Spalte mit eindeutigen Antworten.

Danke für Ihre Zeit

Antwort

15

Dies sollte Ihnen alle eindeutigen Werte aus der Tabelle geben. Ich nehme an, Sie möchten where-Klauseln hinzufügen, die nur für eine bestimmte Frage ausgewählt werden. Diese Lösung erfordert jedoch 5 Unterabfragen und kann langsam sein, wenn Ihre Tabelle sehr groß ist.

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 
+1

das sieht gut aus. Ich werde es jetzt versuchen. – Bryan

+0

Probieren Sie den Drehpunkt, den ich gerade gemacht habe. Ich denke, das ist viel besser. Ich würde lesen, was effizienter ist, aber ich weiß nicht viel über die interne Funktionsweise der verschiedenen Datenbankserver. – achinda99

+0

Brilliant. Ich wünschte, ich hätte daran gedacht. –

1

Ist das, was Sie wollten?

select distinct c1 from t

+1

Schwer zu sagen, ob es ist, aber +1, weil es aussieht wie es sein sollte :) –

+0

ja, es ist schwer zu sagen – JoshBerke

+0

Nein, das wählt eindeutig aus einer Spalte – Bryan

2

Nun können Sie eine UNION verwenden und 5 select-Anweisungen ausführen, eine für jede Spalte in der Tabelle. Es würde in etwa so aussehen:

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

Dies wird Ihnen eine einzige Liste mit allen Antworten geben. Sie haben jedoch immer noch Duplikate, wenn Sie mehrere Kopien derselben Antwort in einer einzigen Spalte haben.

0

In MySQL UND 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 

Für Oracle, fügen FROM DUAL zu jedem der Anzahl auswählt.

5

Ich habe eine Antwort above zur Verfügung gestellt.

Allerdings habe ich einen viel besseren Weg gefunden, es mit UNPIVOT zu tun.

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; 

können Sie bieten jede WHERE-Klausel in der internen Unterabfrage:

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; 
+0

Warum ist das viel besser? – Bryan

+0

Ich mag dieses besser, weil ich logisch mache, was ich tun möchte. Die erste Abfrage erreicht es nur, wo dies meinem Prozess folgt. Wählen Sie auch weniger Unterabfragen. – achinda99

8
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 

Die DISTINCT ist überflüssig, weil die Union keine Zeilen zurück, die für alle Spalten identisch sind. (Wenn Sie duplizierten wollen, oder wenn Sie wissen, dass keine Duplikate vorhanden sind, verwenden Sie UNION ALL für schnellere Leistung)

Dies gibt Ihnen eine einzige Liste alle Antworten enthält. Sie haben jedoch immer noch Duplikate, wenn Sie mehrere Kopien derselben Antwort in einer einzigen Spalte haben.

Das ist nicht der Fall sein sollte, wenn Sie UNION verwenden, nur, wenn Sie UNION verwenden 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) 
+0

Ja, du hast Recht. Da habe ich mich geirrt. Ich testete beide und es gab mir ähnliche Ergebnisse in meinem Datensatz, aber ich war mir nicht sicher über die Besonderheiten, also wenn es Duplikate wären, hätte DISTINCT sich darum gekümmert. Ich habe nie eine UNION in irgendeiner realen Arbeit benutzt, die ich gemacht habe. Nur Bildungszwecke. – achinda99

+0

Sie haben Recht! Eindeutig nicht notwendig. – Bryan

+0

Keine Sorgen! Es lohnt sich, sich daran zu erinnern, immer UNION ALL zu verwenden, wenn Sie wissen, dass es keine Duplikate gibt (oder Sie wollen irgendwelche Duplikate). Speichert den Server, der eine SORTIEREN und De-DUPE machen muss – Kristen

0

Dies ist die genaue Antwort.

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 
2

Spalten von "richtig, falsch1, falsch2, falsch3, falsch4" bedeuten, dass Sie eine falsch gestaltete Datenbank haben. Im Allgemeinen sollte ein Zahlen- oder Buchstabensuffix für einen Spaltennamen eine rote Markierung sein, um das Problem zu überdenken.

Wie Sie festgestellt haben, mussten Sie bei Ihrem Entwurf hacken, um eine Lösung für ein typisches Datenreduktionsproblem zu finden.

+0

Sie sind ein Gauner. Für ein einfaches Quiz ist nichts falsch daran, einen schnellen Fragenkatalog zu erstellen. Versuchen, klüger zu klingen als ... wir sind wir? – Bryan