我在MySQL上遇到SQL请求的问题。我想在已经有数据(生产)的表中填写一个字段。我必须有一些关节来填充数据,但是当我执行查询时出现这个错误:
Error Code: 1242. Subquery returns more than 1 row
我知道这是因为我的子查询中有多个结果,但我必须将这些结果放到我的表中。我的问题:
UPDATE table1
SET application_id = (
SELECT appid FROM (
SELECT t2.application_id AS appid
FROM table2 t2
INNER JOIN table3 t3 ON t3.license_id = t2.licenseid
INNER JOIN table1 t1 ON t1.datetime = t3.datetime
WHERE t1.customer_id = t3.customer_id
ORDER BY t1.datetime DESC
) AS app
)
ORDER BY datetime DESC;
我尝试使用嵌套子查询而不是关节,但我还有另一个问题:
Error Code: 1093. You can't specify target table 'table1' for update in FROM clause
我的查询:
UPDATE table1
SET application_id = (
SELECT t2.application_id
FROM table2 t2
WHERE t2.licenseid IN (
SELECT t3.license_id
FROM table3 t3
WHERE t3.datetime IN (
SELECT t1.datetime
FROM table1 t1
WHERE t1.customer_id IN (
SELECT t3.customer_id
FROM table3 t3
)
ORDER BY t1.datetime DESC
)
)
)
ORDER BY datetime DESC
您有什么建议可以让它发挥作用吗?我想到了一个存储过程,但我想知道是否可以不使用它。
编辑:
我通过存储过程改变了我想要的结果。它工作正常,但当我用生产数据(~90.000行)测试它时,它停在第1144行。我不知道为什么,下一行没有错,我有我需要的所有数据...是否有SQL中REPEAT
循环的限制?这是我的存储过程:
DELIMITER ;;
CREATE PROCEDURE sp1(OUT app_id VARCHAR(36), IN reporting_id VARCHAR(36))
BEGIN
SELECT t1.application_id
INTO app_id
FROM table1 t1
INNER JOIN table2 t2 ON t2.license_id = t1.licenseid
INNER JOIN table3 t3 ON t3.datetime = t2.datetime
WHERE t3.customer_id = t3.customer_id
AND t3.id = reporting_id;
END ;;
DELIMITER ;
DELIMITER ;;
CREATE PROCEDURE sp2(OUT app_id VARCHAR(36), IN reporting_id VARCHAR(36))
BEGIN
SELECT t1.application_id
INTO app_id
FROM table1 t1
INNER JOIN table4 t4 ON t4.license_id = t1.licenseid
INNER JOIN table3 t3ON t3.datetime = t4.datetime
WHERE t3.customer_id = t4.customer_id
AND t3.id = reporting_id;
END ;;
DELIMITER ;
DELIMITER ;;
CREATE PROCEDURE sp3()
BEGIN
DECLARE done INT DEFAULT 0;
DECLARE reporting_id VARCHAR(36);
DECLARE application_id VARCHAR(36);
DECLARE cur1 CURSOR FOR SELECT id FROM table3 ORDER BY datetime DESC;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;
OPEN cur1;
REPEAT
FETCH cur1 INTO reporting_id;
IF NOT done THEN
CALL sp1(application_id, reporting_id);
IF (application_id IS NULL) THEN
CALL sp2(application_id, reporting_id);
END IF;
IF (application_id IS NOT NULL) THEN
START TRANSACTION;
UPDATE table3
SET application_id = application_id
WHERE id = reporting_id;
COMMIT;
END IF;
SET application_id = NULL;
END IF;
UNTIL done END REPEAT;
CLOSE cur1;
END ;;
DELIMITER ;
CALL sp3();
也许我做错了?没有结果可以帮助我找到问题。
答案 0 :(得分:1)
您当前的查询正在尝试更新table1中的每一行,以在table2中拥有每个值。这是不允许的,而你可能想要的是table1中的每一行都有来自table2的相应值
UPDATE table1 t1
INNER JOIN table3 t3 ON t1.datetime = t3.datetime
AND t1.customer_id = t3.customer_id
INNER JOIN table2 t2 ON t3.license_id = t2.licenseid
SET application_id = t2.application_id
请注意,UPDATE中的ORDER BY是不必要的
答案 1 :(得分:0)
您需要通过链接到更新表的WHERE子句来限制子查询,以便它只返回一行。数据库如何知道将哪个值放入哪一行?
UPDATE table1 t1
SET col1 = (SELECT ... FROM table2 t2 WHERE t2.id = t1.some_id)