如何从第一行中减去第二行并在 mysql 中生成输出列
How to subtract second row from first row and generate a output column in mysql
我有一个情况,考虑以下查询:
select
A.cakename, A.status, B.ordertime
from
Cake as A
inner join
Orders as B on A.cakeid = B.cakeid
这个查询的输出
cakename, status, ordertime
Apple Pie, available, 2014-03-20 22:34:46
Apple Pie, available, 2014-10-10 04:00:00
Apple Pie, available, 2015-03-20 22:34:46
Brownie, available, 2014-03-20 22:35:07
Brownie, available, 2015-05-20 22:35:07
Brownie, available, 2014-03-26 22:36:07
Brownie, available, 2015-05-20 14:35:48
Brownie, available, 2015-05-20 22:35:07
Brownie, available, 2015-05-10 22:35:07
现在我想减去 ordertime row n+1 - ordertime row n
并创建一个单独的列来存储结果。现在您可以忽略最后一行,因为不会有下一行。
例如:2014-10-10 04:00:00
- 2014-03-20 22:34:46
这个等式将用于第一行,其结果将存储在一个新列中让我们取 difference of consecutive ordertime
。谁能给我一些解决这种情况的建议?
如果你能帮助创建一个 auto increment column
那就太好了,因为那时我可以自己加入并取差价。
您可以添加一个额外的计算字段:
select
A.cakename, A.status, B.ordertime,
(SELECT MAX(ordertime) FROM Orders AS C WHERE C.ordertime < B.ordertime) AS prev
from
Cake as A
inner join
Orders as B on A.cakeid = B.cakeid
ORDER BY ordertime;
但你最好在 ordertime
上有一个索引:
CREATE INDEX ord_ndx ON Orders(ordertime, cakeid);
实际上,您可以直接计算 the difference from the previous time(假设它不是 NULL;您必须为此提供带 IF 的默认值)。
另一种方式
但是,根据您的体系结构,添加一列可能会更好地为您服务 (previous_order
)。当您插入 订单时,您就知道自己需要什么。使用 TRIGGER
:
查看此示例
CREATE TABLE test ( itemid integer, ordertime timestamp, previous datetime );
CREATE INDEX test_ndx ON test (itemid, ordertime);
CREATE TRIGGER test_set_prev
BEFORE INSERT ON test
FOR EACH ROW
SET NEW.previous = (
SELECT MAX(ordertime) FROM test WHERE itemid = NEW.itemid
);
现在您 table 自动工作。 TIMESTAMP 列将自动更新,previous
列也会自动更新:
insert into test (itemid) values (2);
select sleep(2);
insert into test (itemid) values (2);
+--------+---------------------+---------------------+
| itemid | ordertime | previous |
+--------+---------------------+---------------------+
| 2 | 2015-10-21 09:30:44 | NULL |
| 2 | 2015-10-21 09:30:46 | 2015-10-21 09:30:44 |
+--------+---------------------+---------------------+
它也适用于多个插入:
insert into test (itemid) values (3), (2), (3);
SELECT t.*,
IF(@prev IS NULL ,0 , TIMESTAMPDIFF(SECOND,t.ordertime,@prev)) diff,
@prev = t.ordertime
FROM (
SELECT
A.cakename, A.status, B.ordertime
FROM Cake as A
INNER JOIN Orders as B
ON A.cakeid = B.cakeid
ORDER BY ordertime
) t
我有一个情况,考虑以下查询:
select
A.cakename, A.status, B.ordertime
from
Cake as A
inner join
Orders as B on A.cakeid = B.cakeid
这个查询的输出
cakename, status, ordertime
Apple Pie, available, 2014-03-20 22:34:46
Apple Pie, available, 2014-10-10 04:00:00
Apple Pie, available, 2015-03-20 22:34:46
Brownie, available, 2014-03-20 22:35:07
Brownie, available, 2015-05-20 22:35:07
Brownie, available, 2014-03-26 22:36:07
Brownie, available, 2015-05-20 14:35:48
Brownie, available, 2015-05-20 22:35:07
Brownie, available, 2015-05-10 22:35:07
现在我想减去 ordertime row n+1 - ordertime row n
并创建一个单独的列来存储结果。现在您可以忽略最后一行,因为不会有下一行。
例如:2014-10-10 04:00:00
- 2014-03-20 22:34:46
这个等式将用于第一行,其结果将存储在一个新列中让我们取 difference of consecutive ordertime
。谁能给我一些解决这种情况的建议?
如果你能帮助创建一个 auto increment column
那就太好了,因为那时我可以自己加入并取差价。
您可以添加一个额外的计算字段:
select
A.cakename, A.status, B.ordertime,
(SELECT MAX(ordertime) FROM Orders AS C WHERE C.ordertime < B.ordertime) AS prev
from
Cake as A
inner join
Orders as B on A.cakeid = B.cakeid
ORDER BY ordertime;
但你最好在 ordertime
上有一个索引:
CREATE INDEX ord_ndx ON Orders(ordertime, cakeid);
实际上,您可以直接计算 the difference from the previous time(假设它不是 NULL;您必须为此提供带 IF 的默认值)。
另一种方式
但是,根据您的体系结构,添加一列可能会更好地为您服务 (previous_order
)。当您插入 订单时,您就知道自己需要什么。使用 TRIGGER
:
CREATE TABLE test ( itemid integer, ordertime timestamp, previous datetime );
CREATE INDEX test_ndx ON test (itemid, ordertime);
CREATE TRIGGER test_set_prev
BEFORE INSERT ON test
FOR EACH ROW
SET NEW.previous = (
SELECT MAX(ordertime) FROM test WHERE itemid = NEW.itemid
);
现在您 table 自动工作。 TIMESTAMP 列将自动更新,previous
列也会自动更新:
insert into test (itemid) values (2);
select sleep(2);
insert into test (itemid) values (2);
+--------+---------------------+---------------------+
| itemid | ordertime | previous |
+--------+---------------------+---------------------+
| 2 | 2015-10-21 09:30:44 | NULL |
| 2 | 2015-10-21 09:30:46 | 2015-10-21 09:30:44 |
+--------+---------------------+---------------------+
它也适用于多个插入:
insert into test (itemid) values (3), (2), (3);
SELECT t.*,
IF(@prev IS NULL ,0 , TIMESTAMPDIFF(SECOND,t.ordertime,@prev)) diff,
@prev = t.ordertime
FROM (
SELECT
A.cakename, A.status, B.ordertime
FROM Cake as A
INNER JOIN Orders as B
ON A.cakeid = B.cakeid
ORDER BY ordertime
) t