2012-02-04 49 views
0

我想要通過檢查第一個表上的條件從哪個表中插入值到另一個表的sql查詢。插入...從...中選擇條件的查詢

我必須檢查該行是否存在於第一個表中。如果不存在,則添加,否則不要添加。

在sql中有查詢「insert into select from」模式。

我試過下面的查詢。但它插入許多重複項。

INSERT INTO 
    company_location (company_id, country_id, city_id) 
SELECT 
    ci.company_id, hq_location, hq_city 
FROM 
    company_info ci, company_location cl 
WHERE 
    ci.company_id <> cl.company_id 
    AND cl.country_id <> ci.hq_location 
    AND cl.city_id <> ci.hq_city; 

重複迴避意味着元組(company_id,country_id,city_id)不應再次添加。我必須從更多的4個表格中添加這些表格。

此外我需要查詢刪除company_location重複。即(company_id,country_id,city_id)的組合應該僅存在一次。只保留一個元組並刪除其他行。

+2

將問題分爲兩部分:首先定義一個合適的查詢,返回所需的值,然後使用此查詢將值插入到第二個表中。似乎「插入」部分的問題是無關緊要的。 – 2012-02-04 06:52:18

+0

@ No'am Newman:在sql中有查詢「insert into select」模式。 – 2012-02-04 07:08:26

+0

'company_info'中是否有重複?除此之外,我看不到這個查詢將如何插入'company_location'中已存在的記錄。 – vhallac 2012-02-04 08:42:35

回答

2

我希望這個未經測試的腳本幫助!它只插入一次每個組合。

INSERT INTO company_location 
    (company_id,country_id,city_id) 
SELECT distinct ci.company_id, 
     ci.hq_location, 
     ci.hq_city 
FROM company_info ci 
WHERE ci.company_id NOT IN 
     (SELECT cl1.company_id FROM company_location cl1 
      WHERE cl1.country_id = ci.hq_location 
      AND cl1.city_id = ci.hq_city 
      AND cl1.company_id = ci.company_id) 
+0

它正在工作,如果company_info沒有重複。我也必須從其他具有重複項的表中插入。所以它不適合它。感謝您給予時間。 – 2012-02-04 09:34:50

+0

@Sommath Muluk它也應該工作,如果有重複compan_info,因爲獨特。我希望我理解你的權利。 – chris 2012-02-04 09:39:20

+0

我有問題。您的最後一個條件應該是cl1.company_id = ci.company_id。這就是爲什麼它不考慮這個元組。現在它工作正常。感謝您的支持。還有一個問題,我需要查詢刪除company_location中的重複項。即(company_id,country_id,city_id)的組合應該僅存在一次。只保留一個元組並刪除其他行。 – 2012-02-04 09:44:54

1

使用INSERT IGNORE INTO
Mysql Docs

Specify IGNORE to ignore rows that would cause duplicate-key violations. 
+0

也看到這個:http://stackoverflow.com/questions/2842053/mysql-insert-and-select-order-of-precedence – diEcho 2012-02-04 06:55:43

+0

鏈接沒有幫助。它也是插入重複。表中列出了插入值。 – 2012-02-04 07:07:30

2

INSERT則會忽略的作品。

  • 如果您希望列(或列集合)是唯一的,請在您的表上放置一個UNIQUE約束。如果沒有UNIQUE CONSTRAINT,那麼根據定義,該表不能包含任何不需要的重複項,因爲不放置UNIQUE約束意味着重複項是可取的。
  • 添加UNIQUE(COMPANY_ID,COUNTRY_ID,city_id)(也許這是你該表的主鍵)
  • 使用INSERT忽略

您也可以正確地重寫查詢。查詢不會做你認爲它所做的事情,並且你不能使用18世紀的舊連接語法來做你想做的事。

SELECT * FROM t1, t2, t3 

是一個CROSS JOIN,這意味着它需要行的所有可能組合,從表T1,T2,T3。通常情況下,WHERE包含一些「t1.id = t2.id」條件來限制它並將其變爲INNER JOIN,但「<>」條件不會執行此操作...

您需要一個正確的LEFT JOIN:

INSERT INTO company_location (company_id,country_id,city_id) 
SELECT ci.company_id, hq_location, hq_city 
FROM company_info ci, 
LEFT JOIN company_location cl ON (
    ci.company_id = cl.company_id 
    AND cl.country_id = ci.hq_location 
    AND cl.city_id = ci.hq_city 
) 
WHERE cl.company_id IS NULL 
+0

它正在工作,如果company_info沒有重複。我也必須從其他具有重複項的表中插入。所以它不適合它。感謝您給予時間。 – 2012-02-04 09:34:24

+0

我不明白,對不起;) – peufeu 2012-02-04 14:30:10

1

這裏是對第二個問題的回答;查詢刪除重複條目: 請注意它們未經測試的語句。

解決方案1:

此解決方案僅適用,如果你在你的表有一個行標識。

DELETE FROM company_location 
WHERE id NOT IN 
    (SELECT  MAX(cl1.id) 
    FROM company_location cl1 
     WHERE cl1.company_id = company_location.company_id 
     AND  cl1.country_id = company_location.country_id 
     AND  cl1.city_id = company_location.city_id) 

解決方案2:

這個工作沒有ROW_ID。它將所有數據寫入臨時表中。刪除第一個表格上的內容。並插入每個t​​upel一次。 對此解決方案:如果您在該表上定義了約束,請小心!

CREATE TEMPORARY TABLE tmp_company_location 
(
    company_id bigint 
    ,country_id bigint 
    ,city_id bigint 
); 

INSERT INTO tmp_company_location 
(company_id,country_id,city_id) 
SELECT DISTINCT 
    company_id 
    ,country_id 
    ,city_id 
FROM company_location WHERE 1; 

DELETE FROM company_location; 

INSERT INTO company_location 
SELECT DISTINCT 
    company_id 
    ,country_id 
    ,city_id 
FROM tmp_company_location; 
+0

@cris:需要更改一次。而不是MAX(c1.row_id)MAX(cl1.row_id) 您的解決方案工作正常。再次感謝。 – 2012-02-04 10:50:34