2016-11-11 100 views
1

我有一個表:GROUP_BY,MAX()和only_full_group_by

ID ACCOUNT BALANCE TIME 
1 Bill  10  1478885000 
2 Bill  10  1478885001 
3 James 5  1478885002 
4 Ann  20  1478885003 
5 Ann  15  1478885004 

我想幾個賬戶的最新(基於時間)的平衡。即:

ACCOUNT BALANCE 
Bill  10 
Ann  15 

我嘗試使用這個SQL:

SELECT ACCOUNT, BALANCE, max(TIME) 
FROM T1 
WHERE ACCOUNT IN ('Bill', 'Ann') 
GROUP BY ACCOUNT 

我收到錯誤:

1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'BALANCE' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

我理解的錯誤,並嘗試了不同的sql語句,但還是不明白如何無需多次查詢即可檢索所需數據。

P.S.我使用MySQL 5.7

回答

2
SELECT T1.ACCOUNT, T1.BALANCE, T1.TIME 
FROM T1 
JOIN (SELECT ACCOUNT, max(TIME) as m_time 
     FROM T1 
     WHERE T1.ACCOUNT IN ('Bill', 'Ann') 
     GROUP BY ACCOUNT) T2 
    ON T1.ACCOUNT = T2.ACCOUNT 
AND T1.TIME = T2.m_time 
WHERE T1.ACCOUNT IN ('Bill', 'Ann') 

編輯:多時間的變化更好地利用變量

SQL DEMO:我改變Ann日期爲同

SELECT ACCOUNT, BALANCE, TIME 
FROM (
     SELECT ACCOUNT, BALANCE, TIME, 
      @rn := if(ACCOUNT = @acc, 
         @rn + 1, 
         if(@acc := ACCOUNT, 1, 1) as rn     
     FROM T1, (SELECT @rn := 0, @acc:= '') P 
     WHERE ACCOUNT IN ('Bill', 'Ann') 
     ORDER BY ACCOUNT, TIME desc, BALANCE desc 
    ) T 
WHERE T.rn = 1 

輸出

| ACCOUNT | BALANCE |  TIME | 
|---------|---------|------------| 
| Bill |  10 | 1478885001 | 
|  Ann |  20 | 1478885003 | 
+0

@Matt怎麼樣放在兩個? 'JOIN'更快,因爲派生表沒有索引 –

+0

我有相同的SQL,但TIME在我的表中不是唯一的。由於應用程序的邏輯,我可以有多個行,具有相同的TIME帳戶。在這種情況下,我需要一個包含'group_by(ACCOUNT)'和'max(BALANCE)'的包裝SELECT。是否有更優雅的解決方案? –

+0

@VictorMezrin如果TIME可以重複,那麼我會使用變量來創建一個行號。或者,也許而不是時間ID將是唯一的,並且總是代表以後的時間? – Matt

0

你列在你的選擇是不是在GROUP BY

或添加的所有列不在聚合函數

SELECT ACCOUNT, BALANCE, max(TIME) 
FROM T1 
WHERE ACCOUNT IN ('Bill', 'Ann') 
GROUP BY ACCOUNT, BALANCE 

或更改使用

的的sql_mode
SET sql_mode = '' 

SELECT ACCOUNT, BALANCE, TIME 
    FROM T1 
    where id In (
      select id from T1 where (account, time) in (
         select account, max(time) 
         from t1 
         WHERE ACCOUNT IN ('Bill', 'Ann') group by account)) 
+0

我會收到多個結果 –

+0

@VictorMezrin。在MySQL 5.7中使用asimmetric group(select中的列而不是group by中的)是改變你可以把mysql變成先前的行爲,將sql_mode設置爲'';就像我的答案..在你​​的控制檯或在你的IDE只是執行SET sql_mode =''; – scaisEdge

+0

我還添加了一個查詢,以選擇你需要的行 – scaisEdge

0

錯誤很明顯。如果你想爲每個帳戶的最新餘額,這裏是一個辦法:

select t1.* 
from t1 
where t1.time = (select max(tt1.time) from t1 tt1 where t1.account = tt1.account); 

您可以在外部查詢特定帳戶過濾器添加了where