我有一个包含时间戳和其他值的现有表格,我想在表格中为每一天创建虚拟时间戳
例如
timestamp phase_1 phase_2 phase_3
2014-03-04 12:00:00 0 0 0
2014-03-05 02:00:00 0 0 0
2014=03-06 01:00:00 0 0 0
2014-03-07 00:00:00 0 3 1
应该导致
timestamp phase_1 phase_2 phase_3
2014-03-04 00:00:00 0 0 0 --<< new
2014-03-04 12:00:00 0 0 0
2014-03-05 00:00:00 0 0 0 --<< new
2014-03-05 02:00:00 0 0 0
2014-03-06 00:00:00 0 0 0 --<< new
2014-03-06 01:00:00 0 0 0
2014-03-07 00:00:00 0 3 1
以下查询正常
`select * from Table1
right join
(select
`timestamp`
, phase_1
, phase_2
, phase_3
from Table1
union
select
date(`timestamp`)
, 0
, 1
, 2
from Table1
order by
`timestamp`) `
但我无法将结果插入现有数据库
使用以下查询
`INSERT into Table1
select * from Table1
right join
(select
`timestamp`
, phase_1
, phase_2
, phase_3
from Table1
union
select
date(`timestamp`)
, 0
, 1
, 2
from Table1
order by
`timestamp`) `
我认为这是正确的,但我得到了
: Every derived table must have its own alias: error which i am not sure on how to solve
这是小提琴enter link description here
此外,是否可以在表格中插入虚拟时间戳和值,而这些天数根本不存在?
假设表中的第一行和最后一行之间有两天,并且表中的那些日期没有时间戳,是否可以将这两个日期添加到表中。
我想尽可能避免触发器和程序,因为我对它们一点都不熟悉,因为表是动态生成的,我认为不可能使用它们。
答案 0 :(得分:2)
你必须为你的UNION使用一个别名,但是你必须为你的右连接提供一个JOIN条件。可能你想使用:
INSERT INTO Table1
select a.* from Table1
right join
(
select
`timestamp`
, phase_1
, phase_2
, phase_3
from Table1
union
select
date(`timestamp`)
, 0
, 1
, 2
from Table1
order by
`timestamp`
) as a
ON DATE(a.timestamp) = DATE(Table1.timestamp)
<强>说明:强>
What is the difference between Left, Right, Outer and Inner Joins?提供了对不同连接的非常好的解释。
外部联接需要连接条件,没有条件的内部联接与CROSS JOIN相同,两个表的cartesian product(大多数情况下,一个人想要避免这种情况 - 但永远不会这样)。
如果使用SELECT语句,它在连接中仅作为SELECT语句使用,则此SELECT语句的结果将更改为派生表,并且您必须为此派生表指定一个名称,以便您可以使用派生表的列。
我希望现在会更清楚一点。
答案 1 :(得分:1)
编写此查询的更好(更有效)的方法是删除union
并使用union all
并删除联接。您想要的基本查询似乎是:
select `timestamp`, phase_1, phase_2, phase_3
from Table1
union all
select date(`timestamp`), 0, 1, 2
from Table1 t1
group by date(`timestamp`)
having not exists (select 1 from table1 tt1 where tt1.timestamp = date(t1.timestamp))
order by `timestamp`;
如果值已经出现在表中,则第二个查询中的group by
和having
子句会阻止重复。但老实说,在timestamp
上有一个独特的约束可能更好。
如果要在表中插入行,则只需要查询的第二部分:
INSERT INTO Table1(timestamp, phase_1, phase_2, phase_3)
select distinct date(`timestamp`), 0, 1, 2
from Table1
group by date(`timestamp`)
having not exists (select 1 from table1 tt1 where tt1.timestamp = date(t1.timestamp));
原始数据已存在。
要为不在表中的天数插入“虚拟”时间戳,您需要一种方法来生成具有这些值的行。这可能是MySQL的痛苦。但是,如果您有一个包含所有日期的日历表,您可以执行以下操作:
INSERT INTO Table1(timestamp, phase_1, phase_2, phase_3)
select c.dte, 0, 1, 2
from calendar c join
(select min(date(timestamp)) as mind, max(date(timestmp)) as maxd
from Table1
) tmm
on c.dte between tmm.mind and tmm.maxd and tmm.mind left join
Table1 t1
on date(t1.timestamp) = c.dte
where t1.timestamp is null;