2014-03-13 85 views
3

當在SQL語句中使用時,會話變量的標準行爲是什麼。SQL語句中的mysql會話變量值的優先級

案例1
在以下示例中,如所預期會話變量行爲。

mysql> set @m1=0, @m2=0, @m3=0; 
Query OK, 0 rows affected (0.00 sec) 

mysql> 
mysql> select 
    -> @m1 := 55 m1, @m2 := 42 m2, @m3 := 66 m3, 
    -> @m1, @m2, @m3, 
    -> @b1 := greatest(@m1, @m2, @m3) b1, 
    -> @b2 := ((@total := @m1 + @m2 + @m3) 
    ->   - (@b1 + least(@m1, @m2, @m3))) b2, 
    -> @total total; 
+----+----+----+------+------+------+------+------+-------+ 
| m1 | m2 | m3 | @m1 | @m2 | @m3 | b1 | b2 | total | 
+----+----+----+------+------+------+------+------+-------+ 
| 55 | 42 | 66 | 55 | 42 | 66 | 66 | 55 | 163 | 
+----+----+----+------+------+------+------+------+-------+ 
1 row in set (0.00 sec) 

mysql> 
mysql> set @m1=0, @m2=0, @m3=0; 
Query OK, 0 rows affected (0.00 sec) 

mysql> select 
    -> @m1 := m1+3, @m2 := m2+3, @m3 := m3+3, 
    -> @m1, @m2, @m3, 
    -> @b1 := greatest(@m1, @m2, @m3) b1, 
    -> @b2 := ((@total := @m1 + @m2 + @m3) 
    ->   - (@b1 + least(@m1, @m2, @m3))) b2, 
    -> @total total 
    -> from 
    -> (select 55 m1, 42 m2, 66 m3 union all select 48, 63, 92) marks_list 
    -> ; 
+-------------+-------------+-------------+------+------+------+------+------+-------+ 
| @m1 := m1+3 | @m2 := m2+3 | @m3 := m3+3 | @m1 | @m2 | @m3 | b1 | b2 | total | 
+-------------+-------------+-------------+------+------+------+------+------+-------+ 
|   58 |   45 |   69 | 58 | 45 | 69 | 69 | 58 | 172 | 
|   51 |   66 |   95 | 51 | 66 | 95 | 95 | 66 | 212 | 
+-------------+-------------+-------------+------+------+------+------+------+-------+ 
2 rows in set (0.00 sec) 

上面的例子沒有使用任何聚合函數。

案例2
當類似的聲明用聚合函數像countsumgroup by執行,結果模式是完全不同的。

請給出一個例子:SQL Fiddle

發佈此查詢之前,我試着去了解SQL-Query-Order-of-Operations

回答

1

如果我理解正確,您在詢問select語句中表達式的評估順序。 MySQL的documentation是很清楚,你不能依靠這一點:

在下面的語句,你 可能會認爲MySQL將評估@a第一,然後做一個 分配第二:

SELECT @a, @a:[email protected]+1, ...; 

然而,涉及用戶 變量的表達式的評估順序未定義。

我認爲問題在於您的期望值是按順序分配的。這是不正確的。也就是說,我必須承認,當使用變量時,我會時不時地做出相同的連續性評估假設,主要是因爲懶惰以及它通常工作的事實。

如果你想保證連續評估,然後使用case招:

select (case when (@m := 55) is null then null 
      when (@m := 42) is null then null 
     . . . 
     end) 

的條件case保證順序計算,直到有一個爲真。與null比較確保所有評估。

+0

+1。不涉及彙總時,執行順序非常簡單。通過分組,行爲顯然是令人困惑和不確定的。 –