2017-06-09 48 views
0

設置: 我有兩個表類似於以下內容:MySQL - 如何包含一個與嵌套select的結果相差2行的列?

Table: tickets 
+------+------+------------+----------+----------+--------+-----+--+ 
| Site | Rack | Start Date | End Date | iv_begin | iv_end | ... | | 
+------+------+------------+----------+----------+--------+-----+--+ 
| 1 | 1 | 2016  | 2017  | 900  | 1000 | ... | | 
| 1 | 1 | 2016  | 2017  | 800  | 900 | ... | | 
| 1 | 1 | 2016  | 2017  | 700  | 800 | ... | | 
| 1 | 1 | 2016  | 2017  | 600  | 650 | ... | | 
+------+------+------------+----------+----------+--------+-----+--+ 

Table: sites 
+----+----------+ 
| ID | sitename | 
+----+----------+ 
| 1 | Atlanta | 
| 2 | Boston | 
+----+----------+ 

首先,我不得不使用嵌套查詢得到的結果表然後從查詢。例如:

SELECT Q1.rownum, Q1.name AS "Site", Q1.rack, Q1.iv_begin, Q1.iv_end 
FROM  
    (
    SELECT (@cnt := @cnt + 1) AS rownum, 
    S1.name, T1.rack, T1.batch_start, T1.batch_end, 
    T1.batch, T1.iv_begin, T1.iv_end  
    FROM tickets T1  
    LEFT JOIN sites S1 ON T1.Site = S1.ID   
    CROSS JOIN (SELECT @cnt := 0) AS dummy1  
    WHERE T1.rack = 1   
    ORDER BY 
    T1.batch DESC, 
    T1.iv_begin DESC, 
    T1.iv_end DESC  
    LIMIT 200 
) 
    AS Q1 

爲了得到類似這樣的結果:

+--------+---------+------+----------+--------+ 
| rownum | Site | Rack | iv_begin | iv_end | 
+--------+---------+------+----------+--------+ 
|  1 | Atlanta | 1 |  900 | 1000 | 
|  2 | Atlanta | 1 |  800 | 900 | 
|  3 | Atlanta | 1 |  700 | 800 | 
|  4 | Atlanta | 1 |  600 | 650 | 
+--------+---------+------+----------+--------+ 

問: 我怎麼會一列添加到最終的結果是2個值的差異?例如,我試圖讓列「iv_diff」=(rownum [N] iv_begin) - (rownum [N + 1] iv_end)。 iv_end值應該與前一行的iv_begin值匹配。 iv_diff專欄是要找出是不是這種情況,如果是的話,有什麼不同。

因此產生的表應該是這樣的:

+--------+---------+------+----------+--------+---------+ 
| rownum | Site | Rack | iv_begin | iv_end | iv_diff | 
+--------+---------+------+----------+--------+---------+ 
|  1 | Atlanta | 1 |  900 | 1000 |  0 | 
|  2 | Atlanta | 1 |  800 | 900 |  0 | 
|  3 | Atlanta | 1 |  700 | 800 |  0 | 
|  4 | Atlanta | 1 |  600 | 650 |  50 | 
+--------+---------+------+----------+--------+---------+ 

我試圖複製/粘貼相同的選擇,這樣我也有一個結果Q2,然後試圖LEFT JOIN Q1和Q2 .. (ON Q1.rownum = Q2.rownum + 1)...但我似乎無法得到iv_diff列來返回我需要的結果(有時它會給出累積和,這是不正確的)。

在此先感謝您的幫助!

回答

1

您可以使用其他用戶變量來保存上一行的值。

SELECT Q1.rownum, Q1.name AS "Site", Q1.rack, Q1.iv_begin, Q1.iv_end, Q1.iv_diff 
FROM  
    (
    SELECT (@cnt := @cnt + 1) AS rownum, 
     S1.name, T1.rack, T1.batch_start, T1.batch_end, 
     T1.batch, T1.iv_begin, T1.iv_end, 
     IF(@prev_begin IS NULL, 0, T1.iv_end - @prev_begin) AS iv_diff, @prev_begin := T1.iv_begin 
    FROM tickets T1  
    LEFT JOIN sites S1 ON T1.Site = S1.ID   
    CROSS JOIN (SELECT @cnt := 0, @prev_begin := NULL) AS dummy1  
    WHERE T1.rack = 1   
    ORDER BY 
    T1.batch DESC, 
    T1.iv_begin DESC, 
    T1.iv_end DESC  
    LIMIT 200 
) 
    AS Q1 
+0

謝謝!這工作完美! –

1

如果您的查詢已產生這樣的:

+--------+---------+------+----------+--------+ 
| rownum | Site | Rack | iv_begin | iv_end | 
+--------+---------+------+----------+--------+ 
|  1 | Atlanta | 1 |  900 | 1000 | 
|  2 | Atlanta | 1 |  800 | 900 | 
|  3 | Atlanta | 1 |  700 | 800 | 
|  4 | Atlanta | 1 |  600 | 650 | 
+--------+---------+------+----------+--------+ 

然後,只需添加一個子查詢。

SELECT T1.*, COALESCE(T1.iv_begin - T2.iv_begin, 0) as iv_diff 
FROM (YourQuery) as T1 
LEFT JOIN (YourQuery) as T2 
    ON T1.rownum = T2.rownum - 1 

但通知T1和T2需要使用differente @cnt變量創建rownum

+0

感謝您的回覆。我也嘗試了COALESCE方法,但我從來沒有得到它的工作。 –

+0

很奇怪,因爲與Barmar的IF函數功能相同。無論如何,Barmar的答案要好得多。但是如果你想看到COALESCE [樣本](https://www.w3schools.com/sql/sql_isnull.asp) –