2011-12-20 23 views
1

質問:以下のUNIONクエリでは、従属派生クエリが評価される前に@colをどのように割り当てることができますか?要件:1つのクエリで実行する必要があります。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」値に合致するレコード、および直前と次のレコード:私は3つのレコードを取得することが予想より上の非イオン化クエリから

しかし、最初のクエリの実行では、 "col"のユーザー指定値と一致するレコードが1つだけ得られます。その後の走りは、私が期待している3つを私に与えます。私の推測では、派生クエリprecedingfollowingが評価されるまで、@colは割り当てられていないということです。これは、私が期待していた左から右のトップからボトムの評価順序ではありませんでした。

(私はthis questionに対する答えを絞り込むしようとするが、この困難に走った。)

答えて

2

UNIONにない、あなたの他のクエリと@colの割り当てを行います。

@colに値を割り当てる1つのクエリと、そのレコードを結果に含めるための別のクエリがあります。

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

はい、おかげで、割り当てのための明確なクエリは、私の最初のアプローチでした。ただし、ここでの要件は「すべて1つのクエリで実行する」ことです。私の質問は「どのように」ですか? (今、その要件が水を保有しているかどうかは、別の問題です...しかし、実際の解決方法は+1です) – pilcrow

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'は問題を引き起こしています。 (エイリアスを使って派生したSELECTを選択する必要がありますか?) – pilcrow

+0

また、その割り当ての右辺値として "col"または "@ col"を意味しますか? – pilcrow

関連する問題