2014-06-08 65 views
1

我試圖計算行的差異(如MySQL difference between two rows of a SELECT Statement)在分組結果集:可以將分組表達式與變量賦值一起使用嗎?

create table test (i int not null auto_increment, a int, b int, primary key (i)); 
insert into test (a,b) value (1,1),(1,2),(2,4),(2,8); 

給人

| a | b 
--------- 
| 1 | 1 
| 1 | 2 
| 2 | 4 
| 2 | 8 

這是一個簡單的SQL與組和max(group)結果列:

select 
    data.a, 
    max(data.b) 
from 
    (
     select a, b 
     from test 
     order by i 
    ) as data 
group by a 
order by a 

顯而易見的結果是

| a | max(data.b) 
----------------- 
| 1 | 2 
| 2 | 8 

如果我失敗的是,當我想計算的分組列的行由行差異:

set @c:=0; 
select 
    data.a, 
    max(data.b), 
    @c:=max(data.b)[email protected] 
from 
    (
     select a, b 
     from test 
     order by i 
    ) as data 
group by a 
order by a 

仍然給:

| a | max(data.b) | @c:=max(data.b)[email protected] 
-------------------------------------- 
| 1 | 2   | 2 (expected 2-0=2) 
| 2 | 8   | 8 (expected 8-2=6) 

有誰突出爲什麼按預期,@c變量沒有從分組行更新到分組行?

+0

你的第一個查詢是不是 '明顯的'。事實上,這是錯誤的,或者更準確的說,結果不能保證! – Strawberry

+0

@Strawberry:你能指出相關的文檔嗎?找不到爲什麼這不起作用。我讀過9.4用戶定義的變量,但似乎並不適用(在HAVING,GROUP BY或ORDER BY子句中訪問變量)。 – andig

+1

請參閱https://dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html - 雖然我會承認,這種破解似乎在支持該構造的每個MySQL版本中都能正常工作! – Strawberry

回答

1
SELECT data.a 
    , data.b 
    , @c := data.b - @c 
FROM (
     SELECT a 
      , max(b) AS b 
     FROM test 
     GROUP BY a 
    ) AS data 
ORDER BY a 

Example

+0

確實有效,但我不明白爲什麼我的不是? – andig

+0

@andig:將變量分配給聚合函數結果存在問題(該分配僅被忽略)。 [相關問題](http://stackoverflow.com/q/22384672/3444240) – potashin

0

的 '記錄' 的解決方案可能是這樣的......

SELECT x.* 
    , @c := b - @c c 
    FROM test x 
    JOIN 
    (SELECT a,MAX(b) max_b FROM test GROUP BY a) y 
    ON y.a = x.a 
    AND y.max_b = x.b 
    JOIN (SELECT @c:= 0) vals; 
+0

雖然您的解決方案沒問題,但我仍然無法完全理解實際問題。即使設置SET GLOBAL sql_mode ='ONLY_FULL_GROUP_BY'我的語句仍然執行,他們不應該根據問題的評論? – andig

相關問題