简体   繁体   English

如果该 id 不存在该行,则 SQL 为从另一个表返回的每个 id 插入多行

[英]SQL Insert multiple rows for every id returned from another table if the row does not exist for that id

I need to insert multiple rows into a table for every returned id from another table.我需要为另一个表中的每个返回的 id 将多行插入到一个表中。

For example table1例如表1

id | thing1 |
---+--------|
1  |  true
2  |  false
3  |  true
4  |  false
5  |  true

Example table2示例表2

id |  table1_id  |     column3    |    column4   |
---+-------------|----------------|--------------|
1  |     1       |     'fizz'     |    'fizz'
2  |     1       |     'buzz'     |    'buzz'
3  |     1       | 'hello world'  | 'hello world'
4  |     2       |     'fizz'     |    'fizz'
5  |     2       |     'buzz'     |    'buzz'
6  |     2       | 'hello world'  | 'hello world'

I need to get every id from the above table1 where thing1 is true and insert multiple rows into table2 with the corresponding id as well as 2 other strings.我需要从上面的 table1 中获取每个 id,其中 thing1 为 true,并将多行插入 table2 中,并使用相应的 id 以及 2 个其他字符串。

SELECT id FROM table1 WHERE thing1 = true

would return id 1, 3 and 5.将返回 ID 1、3 和 5。

I would like to insert multiple rows adding the id from table1 as well as 2 other strings into table2.我想插入多行,将 table1 中的 id 以及 2 个其他字符串添加到 table2 中。

INSERT into table2 (table1_id, column3, column4)
VALUES 
    (*id*, 'fizz', 'fizz')
    (*id*, 'buzz', 'buzz')
    (*id*, 'hello world', 'hello world')

I know how to get the ids and to manually insert but how can I do both with one statement?我知道如何获取 id 并手动插入,但如何用一个语句同时完成?

I would suggest an INSERT... SELECT like so:我会建议一个 INSERT ... SELECT 像这样:

INSERT into table2 (table1_id, column3, column4)
SELECT t1.id, s.str, s.str
FROM table1 AS t1
CROSS JOIN (SELECT "fizz" AS str UNION SELECT "buzz" UNION SELECT "hello world") AS s
LEFT JOIN table2 AS t2 ON t1.id = t2.table1_id AND s.str = t2.column3
WHERE t1.thing1 = true
    AND t2.id IS NULL -- Only insert when they are not already present
;

However, this will not guarantee the strings are inserted in the order you've shown.但是,这并不能保证按您显示的顺序插入字符串。

I have not had much call to use CROSS JOINs, so I am not sure how well they play with LEFT JOINs, so if the above does not work out quite right, here are some alternatives below:我没有太多使用 CROSS JOIN 的电话,所以我不确定它们与 LEFT JOIN 的搭配效果如何,所以如果上述方法不太正确,以下是一些替代方案:

INSERT into table2 (table1_id, column3, column4)
SELECT t1.id, s.str, s.str
FROM table1 AS t1
CROSS JOIN (SELECT "fizz" AS str UNION SELECT "buzz" UNION SELECT "hello world") AS s
WHERE t1.thing1 = true
    AND (t2.id, s.str) NOT IN (SELECT table1_id, column3 FROM table2 )
;

or或者

INSERT into table2 (table1_id, column3, column4)
SELECT t1.id, s.str, s.str
FROM table1 AS t1
CROSS JOIN (SELECT "fizz" AS str UNION SELECT "buzz" UNION SELECT "hello world") AS s
WHERE t1.thing1 = true
    AND NOT EXISTS (
           SELECT * 
           FROM table2 AS t2 
           WHERE t2.table1_id = t1.id AND t2.column3 = s.str
        )
;

If Sql Server, the union subquery (including it's surrounding parenthesis and alias) can be replaced with (VALUES ('fizz'), ('buzz'), ('hello word')) AS s(str) .如果是 Sql Server,则联合子查询(包括它周围的括号和别名)可以替换为(VALUES ('fizz'), ('buzz'), ('hello word')) AS s(str)

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

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