1. 程式人生 > >MySQL中INSERT INTO SELECT的使用

MySQL中INSERT INTO SELECT的使用

文章出處:http://www.cnblogs.com/RoadGY/archive/2011/07/22/2114088.html

1. 語法介紹
      有三張表a、b、c,現在需要從表b和表c中分別查幾個欄位的值插入到表a中對應的欄位。對於這種情況,可以使用如下的語句來實現:

INSERT INTO db1_name (field1,field2) SELECT field1,field2 FROM db2_name
 

      上面的語句比較適合兩個表的資料互插,如果多個表就不適應了。對於多個表,可以先將需要查詢的欄位JOIN起來,然後組成一個檢視後再SELECT FROM就可以了:

INSERT INTO a (field1,field2) SELECT * FROM(SELECT b.f1,c.f2 FROM b JOIN c) AS tb
 

      其中f1是表b的欄位,f2是表c的欄位,通過JOIN查詢就將分別來自表b和表c的欄位進行了組合,然後再通過SELECT巢狀查詢插入到表a中,這樣就滿足了這個場景了,如果需要不止2個表,那麼可以多個JOIN的形式來組合欄位。

2. 語法錯誤注意
      需要注意的是巢狀查詢部分最後一定要有設定表別名,如下:

SELECT * FROM (SELECT f1,f2 FROM b JOIN c) AS tb

      即最後的AS tb是必須的(tb這個名稱可以隨意取),即指定一個別名。每個派生出來的新表都必須指定別名,否則在mysql中會報如下錯誤:

ERROR 1248 (42000): Every derived TABLE must have its own alias
 

      另外,MySQL中INSERT INTO SELECT不能加VALUES,即不能寫成如下形式:

INSERT INTO db1_name(field1,field2) VALUES

 SELECT field1,field2 FROM db2_name
 

      否則也會報錯:You have an error in your SQL syntax


     附上一個自己專案中用到的:

INSERTINTOtable_123456789
    (tableID,
    CurrentDate,
    TotalPerson,
    DownFlag,
    StafferID,
    StafferName,
    WorkType,
    Department,
    WorkAddress,
    DownTime,
    UpTime,
    AreaID,
    AreaName,
    TotalAreaPerson,
    EnterTime,
    StationID,
    StationName,
    TotalStationPerson,
    EnterStationTime,
    EnteringTime
    )
        SELECT*FROM
        (
        SELECT
  '123456789'  AStableID,
NOW()AScurrentTime,
' 48'AStotalPerson,
  a.DownFlagASdownFlag,
  a.stafferid          ASStafferId,
  e.staffername        ASStafferName,
e.WorkType          ASWorkType,
  e.Department        ASDepartment,
'工作地點'AS  wordaddress,
a.downtime          ASdowntime,
  a.uptime            ASuptime,
  a.areaid            ASareaID,
  ''                  ASareaName,
'37'AS  totalareaperson,
a.entertime          ASEnterTime,
  d.stationid        ASStationID,
  d.stationName        ASstationName,
  '78'AStotalstationperson,
  a.enterTimeAS  enterstationTime,
  NOW()AS  enteringtime
FROMuploadlocatedata_123456789a
  LEFT JOINuploadstationinfod
    ON(a.StationID=d.StationID)
  LEFT JOINuploadstaffere
    ON(a.StafferID=e.StafferID)
WHEREd.mineId='123456789'
    ANDe.mineId='123456789'
    ANDa.EnteringTime>DATE_ADD(NOW(),INTERVAL'-1 48'DAY_HOUR)
ORDERBYentertimeDESC
        )
        AStb