简体   繁体   English

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

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

I have a an existing table with timestamps and other values and I wanted to create dummy timestamps for each day in the table 我有一个带有时间戳和其他值的现有表,我想为表中的每一天创建虚拟时间戳

For example 例如

    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

should result to 应该导致

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

The following query works fine 以下查询工作正常

`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`) `

but I am not able to insert the result into the exisiting database 但我无法将结果插入现有数据库中

using the following query 使用以下查询

`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`) `

Which i think is correct but i get a 我认为是正确的,但是我得到了

: Every derived table must have its own alias:  error which i am not sure on how to solve

Here is the fiddle enter link description here 这是小提琴在这里输入链接说明

Also, will it be possible to insert dummy timestamp and values for days which are not there at all in the table? 另外,是否可以插入表中根本没有的虚拟时间戳和天数?

Suppose there are two days between the first and last rows in the table and there are no timestamps for those days in the table, will it be possible to add those two dates into the table. 假设表的第一行和最后一行之间有两天,并且表中的那几天没有时间戳,那么可以将这两个日期添加到表中。

I want to avoid trigger and procedures if possible as I am not at all familiar with them and since the table is dynamically generated, i think it wont be possible to use them. 我想尽可能避免使用触发器和过程,因为我根本不熟悉它们,并且由于该表是动态生成的,因此我认为将无法使用它们。

You've got to use an alias name for your UNION, but you've got to provide an JOIN condition for your right join too. 您必须为UNION使用别名,但也必须为您的右联接提供JOIN条件。 Probably you want to use: 可能您想使用:

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)

Remarks: 备注:

What is the difference between Left, Right, Outer and Inner Joins? 左,右,外部和内部连接之间有什么区别? provides a very good explanation of the different joins. 提供了有关不同联接的很好解释。

An outer join needs a join condition, an inner join without a condition is the same as an CROSS JOIN, the cartesian product of both tables (most times one wants to avoid this - but not ever). 外部联接需要一个联接条件,而没有条件的内部联接则与两个表的笛卡尔积 CROSS JOIN相同(大多数情况下,人们希望避免这种情况-但从来没有)。

If you use a SELECT statement, that works perfectly as SELECT statement alone in a join, then the result of this SELECT statement changes into a derived table and you've got to give this derived table a name so you can use the columns of the derived table. 如果您使用SELECT语句,那么该语句与联接中的SELECT语句完全一样,那么此SELECT语句的结果将更改为派生表,并且必须为该派生表命名,以便可以使用派生表。

I hope it will be a little bit more clear now. 我希望现在会更加清楚。

A better (more efficient) way to write this query is to remove the union and use union all and to remove the join. 编写此查询的一种更好(更有效)的方法是删除union并使用union all并删除联接。 The basic query you want seems to be: 您想要的基本查询似乎是:

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`;

The group by and having clauses in the second query prevent duplicates, if the value already appears in the table. 如果值已经出现在表中,则第二个查询中的group byhaving子句将防止重复。 Honestly, though, it is probably better to have a unique constraint on timestamp . 不过,老实说,最好对timestamp设置唯一的约束。

If you want to insert rows into the table, you only need the second portion of the query: 如果要在表中插入行,则只需要查询的第二部分:

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));

The original data is already there. 原始数据已经在那里。

To insert a "dummy" timestamp for days not in the table, you need a way to generate rows with those values. 要为不在表中的天插入“虚拟”时间戳,您需要一种生成具有这些值的行的方法。 This can be a pain in MySQL. 这在MySQL中可能会很痛苦。 But, if you have a calendar table that has all the dates, you can do something like: 但是,如果您有一个包含所有日期的日历表,则可以执行以下操作:

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