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
函数相同。无论如何,巴尔马的答案要好得多。但如果你想看到融合