Search code examples
mysqlloggingjoinmysql-error-1093

How do I rewrite this MySQL query so it doesn't throw this error: You can't specify target table 'crawlLog' for update in FROM clause?


I'm trying to get an id from a companies table where the id is not yet in the crawlLog table. Then I need to insert that companyId into the crawlLog table.

I need to do this in one call so that parallel crawlers don't pull the same url after some other crawler has selected a url, but hasn't inserted it into the crawl log yet. I don't want to lock tables because of other problems that generates.

I get this error from both queries below:

You can't specify target table 'crawlLog' for update in FROM clause

Here are two queries i've tried to do the same thing.

INSERT INTO crawlLog (companyId, timeStartCrawling)
VALUES
(
    (
        SELECT companies.id FROM companies
        LEFT OUTER JOIN crawlLog
        ON companies.id = crawlLog.companyId
        WHERE crawlLog.companyId IS NULL
        LIMIT 1
    ),
    now()
)

I've also tried this, but get the same error:

INSERT INTO crawlLog (companyId, timeStartCrawling)
VALUES
(
    (
        SELECT id
        FROM companies
        WHERE id NOT IN
        (
            SELECT companyId
            FROM crawlLog
        )
        LIMIT 1
    ),
    now()
)

Solution

  • This works and seems like the simplest solution:

    Using the simpler of the two statements in my question, I created an alias for the inner crawlLog table as suggested by @Tocco in the comments, and then removed the necessary encapsulation in VALUES().

    INSERT INTO crawlLog (companyId, timeStartCrawling)
    SELECT id, now()
    FROM companies
    WHERE id NOT IN
    (
        SELECT companyId
        FROM crawlLog AS crawlLogAlias
    )
    LIMIT 1