【问题标题】:Combine INSERT INTO and SELECT for multiple VALUES将 INSERT INTO 和 SELECT 组合为多个 VALUES
【发布时间】:2020-06-16 22:04:40
【问题描述】:

我知道向表中插入多个新行的最常用方法是:

INSERT INTO fruits (fruit, colorId)
VALUES ('apple', 1),
       ('orange', 2),
       ('strawberry', 3);

我也知道我可以插入从 SELECT 获得的结果,即使使用自定义值:

INSERT INTO fruits (fruit, colorId)
SELECT 'pear', id
FROM colors
WHERE color = 'green';

问题是,使用这些选项中的任何一个(或者可能是不同的选项,我不知道),我想使用在这样的查询中获得的结果插入多个值。例如:

SELECT id
FROM colors
WHERE color = 'yellow';

将返回单个值 4yellow 的 id),我想在多个插入查询中重用它,例如

INSERT INTO fruits (fruit, colorId)
VALUES ('banana', id),
       ('lemon', id);

(其中id 应该是4)。有可能吗?


编辑:顺便说一句,我也想避免使用像

这样的子查询
INSERT INTO fruits (fruit, colorId)
VALUES ('banana', (SELECT id FROM colors WHERE color = 'yellow')),
       ('lemon',  (SELECT id FROM colors WHERE color = 'yellow'));

【问题讨论】:

  • "我也想避免使用子查询" - 为什么?
  • @PaulSpiegel 我的意思是我在示例中编写的子查询,这意味着每个插入的值都有一个 SELECT。当然,如果有避免这种情况的子查询,我是非常开放的。
  • 我很确定 MySQL 能够识别它是同一个查询并缓存结果。您也可以按照您知道“黄色”代码的方式编写应用程序代码。例如。在 HTML <option value="4">yellow</option>
  • 一直有人告诉我,一个 SELECT 在另一个 SELECT 中的效率很差,但我还是会尝试一下。谢谢!
  • “一个 SELECT 在另一个 SELECT 中的效率很差” - 嗯,这不是真的。这取决于。

标签: mysql sql-insert insert-select


【解决方案1】:

像这样:

INSERT INTO fruits(fruit, colorid)
SELECT names.name, colors.id
FROM colors
CROSS JOIN (
    SELECT 'banana' AS name UNION ALL
    SELECT 'lemon'
) AS names
WHERE colors.color = 'yellow'

在 MySQL 8 中,您可以使用 table value constructor:

INSERT INTO fruits(fruit, colorid)
SELECT names.column_0, colors.id
FROM colors
CROSS JOIN (VALUES
    ROW('banana'),
    ROW('lemon')
) AS names
WHERE colors.color = 'yellow'

【讨论】:

  • 对不起,我仅限于 MySQL 5.7,所以第二个选项对我无效。你能详细说明第一个选项吗?似乎它需要许多 SELECT 和 UNION ALL。对于更多的值(数百,也许数千......),效率会有多高?
  • 我一般不担心插入语句的效率。您可以考虑使用用户变量的其他答案。
【解决方案2】:

顺便说一句,你可以这样做:

DECLARE @Id INT
SET @Id = (SELECT id FROM colors WHERE color = 'yellow')
INSERT INTO fruits (fruit, colorId)
VALUES ('banana', @Id),
   ('lemon',  @Id);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 1970-01-01
    • 2016-06-09
    • 2010-10-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多