2011-12-20 123 views
1

问题:在下面的UNIONized查询中,如何强制@col在对依赖派生查询进行求值之前分配?要求:它需要在一个查询中完成。MySQL UNION中语句评估和变量赋值的顺序

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; 

背景:从工会组织上面的查询我有望获得三个记录:记录匹配的精确和独特的“关口”值将紧随前面和后面的记录的“关口”的命令。

但是,第一个运行的查询只产生一条记录,一条匹配用户提供的“col”值。随后的运行给了我期望的三个。我的推论是@col直到衍生查询precedingfollowing被评估后才被分配 - 这不是我所期望的从左到右的从上到下的评估顺序。

(我正在试图回答细化到this question,但跑在这个困难。)

回答

2

不要UNION @col的分配与其他查询。

有一个查询为@col赋值,还有一个单独的查询将该记录包含在结果中。

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

是的,谢谢,用于分配一个独特的查询是我的第一种方法。但是,这里的要求是“在一个查询中完成”,我的问题是“如何?” (现在,对于工作解决方案来说,这个需求是否成立是个单独的问题......) – pilcrow 2011-12-20 16:38:01

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

*“您的SQL语法错误”*。第一个'@ colx'造成麻烦。 (你是否需要使用别名进行正确的SELECTing派生查询?) – pilcrow 2011-12-20 16:40:37

+0

另外,您是否将该“col”或“@ col”作为该赋值中的右值? – pilcrow 2011-12-20 16:42:23