Question: In the UNIONized query below, how can I force @col
to be assigned before the dependent derived queries are evaluated? Requirement: it needs to be done in one query.
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: From the UNIONized query above I expected to obtain three records: a record matching an exact and unique "col" value, and the immediately preceding and following records as ordered by "col".
However, the first run of the query yields just one record, the one matching the user-supplied value for "col". Subsequent runs give me the three I expect. My inference is that @col
is not assigned until after the derived queries preceding
and following
are evaluated — that was not the left-to-right-top-to-bottom evaluation order I'd expected.
(I was attempting to refine an answer to this question, but ran in to this difficulty.)