簡體   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