繁体   English   中英

将mysql查询的结果插入现有表

[英]Inserting the results of a mysql query into existing table

我有一个带有时间戳和其他值的现有表,我想为表中的每一天创建虚拟时间戳

例如

    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

这是小提琴在这里输入链接说明

另外,是否可以插入表中根本没有的虚拟时间戳和天数?

假设表的第一行和最后一行之间有两天,并且表中的那几天没有时间戳,那么可以将这两个日期添加到表中。

我想尽可能避免使用触发器和过程,因为我根本不熟悉它们,并且由于该表是动态生成的,因此我认为将无法使用它们。

您必须为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)

备注:

左,右,外部和内部连接之间有什么区别? 提供了有关不同联接的很好解释。

外部联接需要一个联接条件,而没有条件的内部联接则与两个表的笛卡尔积 CROSS JOIN相同(大多数情况下,人们希望避免这种情况-但从来没有)。

如果您使用SELECT语句,那么该语句与联接中的SELECT语句完全一样,那么此SELECT语句的结果将更改为派生表,并且必须为该派生表命名,以便可以使用派生表。

我希望现在会更加清楚。

编写此查询的一种更好(更有效)的方法是删除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 byhaving子句将防止重复。 不过,老实说,最好对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;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM