Delete using left outer join in Postgres

前端 未结 4 1208
轮回少年
轮回少年 2021-02-06 22:50

I am switching a database from MySQL to Postgres SQL. A select query that worked in MySQL works in Postgres but a similar delete query does not.

I have two tables of da

相关标签:
4条回答
  • 2021-02-06 23:34

    As others have noted, you can't LEFT JOIN directly in a DELETE statement. You can, however, self join on a primary key to the target table with a USING statement, then left join against that self-joined table.

    DELETE FROM tv_episodes
    USING tv_episodes AS ed
    LEFT OUTER JOIN data AS nd ON
       ed.file_name = nd.file_name AND 
       ed.path = nd.path
    WHERE
       tv_episodes.id = ed.id AND
       ed.cd_name = 'MediaLibraryDrive' AND nd.cd_name IS NULL;
    

    Note the self join on tv_episodes.id in the WHERE clause. This avoids the sub-query route provided above.

    0 讨论(0)
  • 2021-02-06 23:39

    Instead of

    DELETE ed
    FROM tv_episodes AS ed
    LEFT OUTER JOIN data AS nd ON
    ed.file_name = nd.file_name AND 
    ed.path = nd.path
    WHERE ed.cd_name = 'MediaLibraryDrive' AND nd.cd_name IS NULL;
    

    please try

    DELETE FROM tv_episodes
    WHERE cd_name = 'MediaLibraryDrive' AND 
      (tv_episodes.filename, tv_episodes.path IN
        (SELECT ed.filename, 
        ed.path 
        FROM tv_episodes AS ed 
        INNER JOIN data AS nd 
          ON ed.file_name = nd.file_name 
            AND ed.path = nd.path
        WHERE nd.cd_name IS NULL)
      )
      ;
    

    JOIN is not valid in a DELETE query according to the postgresql documentation. You might need to concatenate the left and right parts of the IN expression.

    0 讨论(0)
  • 2021-02-06 23:40

    Use the DELETE... USING syntax:

    DELETE FROM tv_episodes USING data WHERE 
    tv_episodes.file_name = data.file_name AND 
    tv_episodes.path = data.path AND 
    tv_episodes.cd_name = 'MediaLibraryDrive' AND 
    data.cd_name IS NULL;
    
    0 讨论(0)
  • 2021-02-06 23:45

    As bf2020 points out, postgres does not support JOINs when conducting a DELETE query. The proposed solution of a sub-query made me think of the solution. Refine the SELECT query from above and employ it as a sub-query to a DELETE query statement:

    DELETE FROM tv_episodes 
    WHERE id in (
        SELECT ed.id
        FROM tv_episodes AS ed
        LEFT OUTER JOIN data AS nd ON
        ed.file_name = nd.file_name AND 
        ed.path = nd.path
        WHERE ed.cd_name = 'MediaLibraryDrive' AND nd.cd_name IS NULL
    );
    

    Sub-queries can often be inefficient consuming time and CPU resources with some database systems, especially MySQL. From my experience I try to avoid using a sub-query due to that inefficiency plus that such queries are sometimes an easy way out to honing one's skill like learning JOIN syntax.

    Since postgre does not permit delete queries using join, the above is the solution that works.

    0 讨论(0)
提交回复
热议问题