2017-08-21 42 views
1

我正在試驗的數據集具有此SQLFiddle中給出的結構。mysql與組運行的差異

create table readings_tab (id int, site varchar(15), logged_at datetime, reading smallint); 

insert into readings_tab values (1, 'A', '2017-08-21 13:22:00', 2500); 
insert into readings_tab values (2, 'B', '2017-08-21 13:22:00', 1210); 
insert into readings_tab values (3, 'C', '2017-08-21 13:22:00', 3500); 
insert into readings_tab values (4, 'A', '2017-08-22 13:22:00', 2630); 
insert into readings_tab values (5, 'B', '2017-08-22 13:22:00', 1400); 
insert into readings_tab values (6, 'C', '2017-08-22 13:22:00', 3800); 
insert into readings_tab values (7, 'A', '2017-08-23 13:22:00', 2700); 
insert into readings_tab values (8, 'B', '2017-08-23 13:22:00', 1630); 
insert into readings_tab values (9, 'C', '2017-08-23 13:22:00', 3950); 
insert into readings_tab values (10, 'A', '2017-08-24 13:22:00', 2850); 
insert into readings_tab values (11, 'B', '2017-08-24 13:22:00', 1700); 
insert into readings_tab values (12, 'C', '2017-08-24 13:22:00', 4200); 
insert into readings_tab values (13, 'A', '2017-08-25 13:22:00', 3500); 
insert into readings_tab values (14, 'B', '2017-08-25 13:22:00', 2300); 
insert into readings_tab values (15, 'C', '2017-08-25 13:22:00', 4700); 

當前查詢:

select t.rownum, t.logged_on, t.tot_reading, coalesce(t.tot_reading - t3.tot_reading, 0) AS daily_generation 
from 
    (
    select @rn:[email protected]+1 AS rownum, date(t.logged_at) AS logged_on, sum(t.reading) AS tot_reading 
    from readings_tab t, (SELECT @rn:=0) t2 
    group by date(t.logged_at) 
    order by date(t.logged_at) desc 
) t 
    left join 
    (
    select @rn:[email protected]+1 AS rownum, date(t.logged_at) AS logged_on, sum(t.reading) AS tot_reading 
    from readings_tab t, (SELECT @rn:=0) t2 
    group by date(t.logged_at) 
    order by date(t.logged_at) desc 
) t3 on t.rownum = t3.rownum + 1 
    order by t.logged_on desc; 

我期待下面的輸出。我不需要結果集中的公式(3500 + 2300 + 4700等)。只是包括它使其可以理解。

----------------------------------------------------------------- 
| logged_on |  tot_reading   | daily_generation | 
----------------------------------------------------------------- 
| 2017-08-25 | (3500+2300+4700) = 10500 | (10500 - 8750) = 1750 | 
| 2017-08-24 | (2850+1700+4200) = 8750 | (8750-8280) = 470 | 
| 2017-08-23 | (2700+1630+3950) = 8280 | (8280-7830) = 450 | 
| 2017-08-22 | (2630+1400+3800) = 7830 | (7830-7210) = 620 | 
| 2017-08-21 | (2500+1210+3500) = 7210 |      0 | 
----------------------------------------------------------------- 

我不明白爲什麼它不會產生預期的輸出。有人可以幫忙嗎?

+0

設法得到預期的輸出通過具有'的t.rownum = t3.rownum'代替't.rownum = t3.rownum - 1'。但我不明白它是如何給出正確的結果。 –

+0

,因爲用戶變量正在重新使用。在第二個查詢中將rn更改爲rn2,您將看到您需要再次使用-1。添加t3.rownum到你的選擇,你會看到它爲什麼工作。行1的t2RN未初始化。但是如果你製作@ rn2,那麼它就是,你會得到你以後的東西。 http://sqlfiddle.com/#!9/cafe7/40/0 – xQbert

+0

哦,如果你改變用戶變量,你會發現公式導致負數,所以我認爲這些數值是倒退的。 – xQbert

回答

1

如果使用變量確保它們對每個子查詢都是唯一的,那麼您可能會得到不正確的結果。我建議以下調整查詢(其中有一些額外的列來幫助跟蹤發生了什麼):

select 
     t.rownum, t.logged_on, t.tot_reading 
    , coalesce(t.tot_reading - t3.tot_reading, 0) AS daily_generation 
    , t3.rownum t3_rownum 
    , t3.tot_reading t3_to_read 
    , t.tot_reading t_tot_read 
from 
    (
    select @rn:[email protected]+1 AS rownum, date(t.logged_at) AS logged_on, sum(t.reading) AS tot_reading 
    from readings_tab t 
    cross join (SELECT @rn:=0) t2 
    group by date(t.logged_at) 
    order by date(t.logged_at) desc 
) t 
    left join 
    (
    select @rn2:[email protected]+1 AS rownum, date(t.logged_at) AS logged_on, sum(t.reading) AS tot_reading 
    from readings_tab t 
    cross join (SELECT @rn2:=0) t2 
    group by date(t.logged_at) 
    order by date(t.logged_at) desc 
) t3 on t.rownum = t3.rownum + 1 
    order by t.logged_on desc 
    ; 

注意我也推薦使用顯式CROSS JOIN語法,因爲它導致更容易理解的人誰需要保持這個查詢。

下面是結果(&也見http://sqlfiddle.com/#!9/dcb5e2/1

| rownum | logged_on | tot_reading | daily_generation | t3_rownum | t3_to_read | t_tot_read | 
|--------|------------|-------------|------------------|-----------|------------|------------| 
|  5 | 2017-08-25 |  10500 |    1750 |   4 |  8750 |  10500 | 
|  4 | 2017-08-24 |  8750 |    470 |   3 |  8280 |  8750 | 
|  3 | 2017-08-23 |  8280 |    450 |   2 |  7830 |  8280 | 
|  2 | 2017-08-22 |  7830 |    620 |   1 |  7210 |  7830 | 
|  1 | 2017-08-21 |  7210 |    0 | (null) |  (null) |  7210 |