Reihenfolge der Kontoauswertung und variableszuweisung in MySQL UNIONs

Frage: Wie kann ich in der UNION-basierten Abfrage erzwingen, dass @col zugewiesen wird, bevor die abhängigen abgeleiteten Abfragen ausgewertet werden? Voraussetzung: Es muss in einer Abfrage durchgeführt werden.

 CREATE TABLE tbl (col CHAR(1) NOT NULL UNIQUE); INSERT INTO tbl (col) VALUES ('a'), ('b'), ('c'), ('d'), ('e'), ...; -- Now, for some value of "col", fetch that record and the -- immediately preceding and following records as ordered by "col" -- -- If you care to test this, be sure to SET @col := NULL before -- subsequent executions to simulate a "fresh" MySQL session... -- SELECT @col := col AS col -- Fetch particular record given a value of FROM tbl -- "col". WHERE col = 'd' UNION ALL SELECT col -- Fetch the immediately preceding record, FROM ( SELECT col -- ordered by "col" FROM tbl WHERE col < @col ORDER BY col DESC LIMIT 1) preceding UNION ALL SELECT col -- Fetch the immediately following record, FROM ( SELECT col -- ordered by "col" FROM tbl WHERE col > @col ORDER BY col ASC LIMIT 1) following ORDER BY col ASC; 

background: Von der obigen UNION-Abfrage erwartete ich, drei datasätze zu erhalten: einen datasatz, der einem genauen und eindeutigen "col" -Wert entspricht, und die unmittelbar vorhergehenden und folgenden datasätze, wie von "col" angeordnet.

Die erste Ausführung der Abfrage ergibt jedoch nur einen datasatz, der mit dem vom Benutzer angegebenen Wert für "col" übereinstimmt. Nachfolgende Läufe geben mir die drei, die ich erwarte. Meine Schlussfolgerung ist, dass @col erst zugewiesen wird, nachdem die abgeleiteten Abfragen, die preceding und following Abfragen ausgewertet wurden – das war nicht die Bewertungsreihenfolge von links nach rechts, von oben nach unten, die ich erwartet hatte.

(Ich habe versucht, eine Antwort auf diese Frage zu verfeinern, bin aber auf diese Schwierigkeit gestoßen.)

Vereinigen Sie nicht die Zuordnung von @col mit Ihren anderen Abfragen.

Haben Sie eine Abfrage, um @col einen Wert zuzuordnen, und eine separate Abfrage, um diesen datasatz in Ihre Ergebnisse aufzunehmen.

 SELECT @col := col AS col -- Fetch particular record given a value of FROM tbl -- "col", assigning the identifier to @col. WHERE col = 'd' SELECT col -- Now include the above record in the FROM tbl -- Final result-set WHERE col = @col UNION ALL SELECT col -- Fetch the immediately preceding record, FROM ( SELECT col -- ordered by "col" FROM tbl WHERE col < @col ORDER BY col DESC LIMIT 1) preceding UNION ALL SELECT col -- Fetch the immediately following record, FROM ( SELECT col -- ordered by "col" FROM tbl WHERE col > @col ORDER BY col ASC LIMIT 1) following ORDER BY col ASC; 
 SELECT @col := col AS col -- Fetch particular record given a value of FROM tbl -- "col". WHERE col = 'd' UNION ALL SELECT col -- Fetch the immediately preceding record, FROM (@colx:=col), -- Assigne it here ( SELECT col -- ordered by "col" FROM tbl WHERE col < @colx ORDER BY col DESC LIMIT 1) preceding UNION ALL SELECT col -- Fetch the immediately following record, FROM (@colx:=col), -- Assign it here also ( SELECT col -- ordered by "col" FROM tbl WHERE col > @colx ORDER BY col ASC LIMIT 1) following ORDER BY col ASC;