在MySQL中使用子查询的INSERT INTO语句

64

我有这个语句:

INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
    VALUES (1, 2, (SELECT item_costprice FROM qa_items WHERE item_code = 1));

我正在尝试插入一个值来复制item_costprice相同的数据,但显示错误:

Error Code: 1136. Column count doesn't match value count at row 1

我该如何解决这个问题?
6个回答

107

SELECT 语句内使用带别名的数字字面量。不需要在 SELECT 成分周围加上 ()

INSERT INTO qa_costpriceslog (item_code, invoice_code, item_costprice)
  SELECT
    /* Literal number values with column aliases */
    1 AS item_code,
    2 AS invoice_code,
    item_costprice
  FROM qa_items 
  WHERE item_code = 1;

请注意,在使用INSERT INTO...SELECT语句时,别名实际上是不必要的。你只需要写成SELECT 1, 2, item_costprice即可。但在普通的SELECT语句中,你需要使用别名才能访问返回的列。


12

您可以简单地例如。

INSERT INTO modulesToSections (fk_moduleId, fk_sectionId, `order`) VALUES
    ((SELECT id FROM modules WHERE title="Top bar"),0,-100);

1
查询错误 (1242): 子查询返回多行数据。语法正确,但只适用于单行数据。 - stamster
在使用子查询时最好设置一个限制状态,就像这个答案一样。例如:选择id from modules where title="Top bar" limit 1 - Hashan
这个可以运行,但是有没有更好的方法来实现它,而不需要在每一行要添加的子查询中放置一个子查询呢? - shieldgenerator7

4

我对“全有或全无”的回答感到失望。我需要(再次)INSERT一些数据,并从现有表中SELECT一个id

INSERT INTO table1 (id_table2, name) VALUES ((SELECT id FROM table2 LIMIT 1), 'Example');

INSERT查询中的子查询应该使用括号作为分隔符,除了逗号。

对于那些在INSERT中使用SELECT时遇到困难的人,我建议先独立测试您的SELECT,确保两个查询的列数匹配。


2
您的插入语句左侧列数过多或右侧列数不足。在VALUES之前的部分中列出了7个列,但是在VALUES之后的第二部分中仅返回了3个列:1、2,然后子查询只返回了1个列。 编辑: 在有人修改查询之前确实如此。

0

如果您有多个字符串值需要添加,您可以将它们放入临时表中,然后与您想要的值进行交叉连接。

-- Create temp table    
CREATE TEMPORARY TABLE NewStrings (
        NewString VARCHAR(50)
    );
-- Populate temp table
INSERT INTO NewStrings (NewString) VALUES ('Hello'), ('World'), ('Hi');

-- Insert desired rows into permanent table
INSERT INTO PermanentTable (OtherID, NewString)
    WITH OtherSelect AS (
        SELECT OtherID AS OtherID FROM OtherTable WHERE OtherName = 'Other Name'
    )
    SELECT os.OtherID, ns.NewString
    FROM OtherSelect os, NewStrings ns;

这样,你只需要在一个地方定义字符串,并且只需要在一个地方进行查询。如果你像我最初那样使用子查询,就像Elendurwen和John建议的那样,你必须在每一行中输入子查询。但是使用临时表和CTE的方式,你只需要编写一次查询语句。

0
作为对Michael Berkowski的好回答的补充: 您还可以动态添加字段(或者如果您正在使用php脚本,则可以预先准备它们),如下所示:
   INSERT INTO table_a(col1, col2, col3)
     SELECT
       col1,
       col2,
       CURRENT_TIMESTAMP()
     FROM table_B 
     WHERE b.col1 = a.col1;

如果您需要进行转移 而不添加新数据,您可以使用 NULL 作为占位符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接