2016-05-26 14 views
1

Entschuldigung für diese neue Frage, aber ich habe mir in den letzten paar Stunden die Haare geraubt, auf etwas, das nicht einfacher sein könnte.Union scheint nicht zu funktionieren wie erwartet. Weniger Zeilen zurückgeben

Ich habe eine Tabelle (single_elim):

id_tournament phase player1 player2 
    1    1  1   2 
    1    1  3   4 
    1    1  5   10 

und ich versuche, eine Abfrage zu schreiben, die ein Spieler mir seinen Gegner gegeben gibt. Leider kann ich nicht wissen, ob der Spieler in der player1 Spalte oder den Spieler sein 2 (aber ich weiß, dass sie sich gegenseitig ausschließen) Spalte so erwartete ich eine mögliche Lösung zu sein:

SELECT p AS opponent FROM (

    (
     SELECT player1 as p FROM single_elim 
     WHERE 
      id_tournament = 1 AND 
      phase = 1 AND 
      player2 = 4 

    ) UNION ALL (

     SELECT player2 as p FROM single_elim 
     WHERE 
      id_tournament = 1 AND 
      phase = 1 AND 
      player1 = 4 
    ) 

) x; 

jedoch die Aussage Rückkehr 0 Zeilen.

Wenn ich laufe die einzige Anweisung:

SELECT player1 as p FROM single_elim 
    WHERE 
     id_tournament = 1 AND 
     phase = 1 AND 
     player2 = 4 

dass player2 Unter der Annahme, in der Spalte sein wird 4 dann funktioniert es und ich bekomme eine eine Zeile Ergebnis mit p = 3. ich mit UNION und ich auch versucht haben, Ich habe auch verschiedene Arten von Abfragen ausprobiert, die ich hätte erwarten können zu arbeiten, meine Schlussfolgerung ist, dass ich etwas Grundlegendes über die Funktionsweise der Gewerkschaft vermisse, aber nach einigen Recherchen habe ich es nicht geschafft, es herauszufinden.

Ein weiteres Beispiel für Abfrage, die allein aber nicht mit einer Vereinigung arbeitete, war:

SELECT * FROM (

     SELECT COUNT(*) as n, player2 as p FROM helper 
     WHERE id_tournament = 1 AND player1 = 4 AND phase = 1 

    ) UNION ALL (

     SELECT COUNT(*) as n, player1 as p FROM helper 
     WHERE id_tournament = 1 AND player2 = 4 AND phase = 1 

    ) 
) x WHERE n = 1; 

Jede Hilfe, vielen Dank geschätzt wird.

Antwort

0

Das Verhalten, das Sie beobachten, scheint seltsam, die erste UNION sollte eine Zeile zurückgegeben haben. (Sind die Datenwerte Integer-Typen oder String-Typen?)

Sie sollten jedoch UNION nicht benötigen, es sei denn, es handelt sich um eine riesige Tabelle, in der Sie die Indexnutzung so weit wie möglich optimieren müssen.

SELECT CASE WHEN player1 = 4 THEN player2 ELSE player1 END as p 
    FROM single_elim 
    WHERE id_tournament = 1 
    AND phase = 1 
    AND (player1 = 4 OR player2 = 4) 
    ; 
+0

Tha Werte sind alle Ints. Ja, Ihre Lösung funktioniert! Und es scheint viel eleganter zu sein. Danke vielmals. Ich dachte, es muss ein Fehler in mySql 5.6 sein, aber ich habe keinen Hinweis darauf gefunden, was wirklich seltsam ist. – WiserTheBassist

0

Ich denke, dass die Klammern es vermasseln. In jedem Fall brauchen Sie die Wrapping-Select-Abfrage nicht, die Union ist genug. das funktioniert gut:

SELECT player1 as p FROM single_elim 
    WHERE 
     id_tournament = 1 AND 
     phase = 2 AND 
     player2 = 4 
UNION ALL 
    SELECT player2 as p FROM single_elim 
    WHERE 
     id_tournament = 1 AND 
     phase = 2 AND 
     player1 = 4;