MySQL-如何包含与嵌套选择结果相差2行的列?

MySQL-如何包含与嵌套选择结果相差2行的列?,mysql,left-join,Mysql,Left Join,设置: 我有两个类似于以下内容的表格: Table: tickets +------+------+------------+----------+----------+--------+-----+--+ | Site | Rack | Start Date | End Date | iv_begin | iv_end | ... | | +------+------+------------+----------+----------+--------+-----+--+ | 1 |

设置: 我有两个类似于以下内容的表格:

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来获取一个结果表,然后从中进行查询。例如:

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 |
+--------+---------+------+----------+--------+
问题: 如何向最终结果中添加一列,即两行值之差?例如,我试图获取列“iv_diff”=(rownum[N]iv_begin)-(rownum[N+1]iv_end)。iv_结束值应与前一行的iv_开始值匹配。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,然后尝试左键连接Q1和Q2…(在Q1.rownum=Q2.rownum+1)…但我似乎无法让iv_diff列返回我需要的结果(有时它会给出一个累积和,这是不对的)


提前感谢您的帮助

如果您的查询已经生成了以下内容:

+--------+---------+------+----------+--------+
| 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需要使用different
@cnt
变量来创建
rownum

+--------+---------+------+----------+--------+
| 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需要使用different
@cnt
变量来创建
rownum
您可以使用另一个用户变量来保存前一行的值

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

可以使用另一个用户变量保存前一行中的值

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

谢谢你的回复。我也尝试过合并方法,但我从来没有让它起作用。这很奇怪,因为它的函数与Barmar answer中的
IF
函数相同。无论如何,巴尔马的答案要好得多。但如果你想看到凝聚,谢谢你的回应。我也尝试过合并方法,但我从来没有让它起作用。这很奇怪,因为它的函数与Barmar answer中的
IF
函数相同。无论如何,巴尔马的答案要好得多。但如果你想看到融合