1

I have an issue with an SQL request on MySQL. I want to fill a field in a table which has already data (production). I must have some joints to get the data to fill, but I have this error when I execute my query :

Error Code: 1242. Subquery returns more than 1 row

I know that is because I have multiple results in my subquery but I must have these to fil my table. My query :

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;

I tried with nested subqueries instead of joints but I have another problem :

Error Code: 1093. You can't specify target table 'table1' for update in FROM clause

My query :

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 

Have you any suggestions to make it work ? I think of a stored procedure, but I would like to know if it's possible to do without it.

EDIT :

I've change my way to get the result I want, with stored procedures. It works fine, but when I test it with production data (~90.000 rows) it stops at the row 1144. I don't know why, next row isn't wrong, I have all data I need... Is there a limit for REPEAT loop in SQL ? Here is my stored procedures :

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();

Maybe I'm doing wrong ? No results help me to find the problem.

3
  • 2
    How would you set a single column to values from multiple rows? Commented Aug 28, 2015 at 13:53
  • @GordonLinoff : In fact I want to get for my new field (application_id) the right value from existing datas, and I can do it with my subquery (bound from some foreign keys), but when I want to fill them, it doesn't work. Commented Aug 28, 2015 at 13:57
  • I flagged it for closure because it is not clear at all what you want. You can improve your question by showing sample data from source tables and what it should look like in the destination table. Commented Aug 28, 2015 at 14:15

2 Answers 2

2

You current query is trying to update EVERY row in table1 to have EVERY value in table2. This is disallowed, rather what you probably want is EACH row in table1 to have its corresponding value from 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

Note that ORDER BY in an UPDATE is unnecessary

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your response, but your query seems to be wrong, at FROM line ? It says that this input is not valid at this place. I'm on MySQL by the way
Ah, I was using syntax for the wrong flavour of SQL
0

You need to limit the subquery by a WHERE clause linked to the updated table so that it only returns one row. How else would the database know which value to put into which row?

UPDATE table1 t1
SET col1 = (SELECT ... FROM table2 t2 WHERE t2.id = t1.some_id)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.