DELETE从两个表中的行不具有一个ID匹配相同的两个表的另一查询

问题描述 投票:1回答:2

下面不一定使用正确的语法,而是意在表达我的意图:

DELETE FROM wp_posts, wp_postmeta 
 WHERE wp_posts.ID <> min(f.post_ID), wp_postmeta.post_id <> min(f.post_ID) 

(这分别是真正2只删除组合在一个,与用于在第一和第二表WHERE条件。)

其中min(f.post_ID)来自下方的虚拟表:

SELECT Min(f.post_id), 
       f.post_title, 
       f.meta_value 
FROM   (SELECT wp_posts.post_title, 
               Min(wp_postmeta.meta_value) AS minprice 
        FROM   wp_postmeta 
               JOIN wp_posts 
                 ON wp_postmeta.post_id = wp_posts.id 
        WHERE  wp_posts.post_type = 'Product' 
               AND wp_postmeta.meta_key = '_regular_price' 
        GROUP  BY wp_posts.post_title) AS x 
       INNER JOIN (SELECT wp_postmeta.post_id, 
                          wp_posts.post_title, 
                          wp_postmeta.meta_value 
                   FROM   wp_postmeta 
                          JOIN wp_posts 
                            ON wp_postmeta.post_id = wp_posts.id 
                   WHERE  wp_posts.post_type = 'Product' 
                          AND wp_postmeta.meta_key = '_regular_price' 
                   ORDER  BY wp_posts.post_title, 
                             wp_postmeta.meta_value) AS f 
               ON x.post_title = f.post_title 
                  AND f.meta_value = x.minprice 
GROUP  BY f.post_title 

如何将查询看看吗?

编辑:这是值得考虑的是,从一个表中删除之前,其他任何实施将改变第二删除的结果。 (第二DELETE将受影响的首先删除,因为从子查询表中的项目先删除被删除。)

mysql sql syntax
2个回答
1
投票

你不从两个表在同一时间删除。如果表是相关的,你这个孩子,然后父删除。如果他们不相关的删除可以按任何顺序发生。如果他们无关,但有依赖于它们的其他表(即他们是父母自己生孩子),那么数据必须从这些其它表的第一被清零。如果关系限制设置为级联删除模式,则子表中的数据时,将自动父表中的数据被删除删除。如果删除必须发生,因为一个全有或全无(即如果先删除成功后的第二删除失败,你不想先删除成功),应在交易完成。

从而:

DELETE FROM wp_postmeta WHERE post_id NOT IN (

  SELECT Min(f.post_id)
  FROM   (SELECT wp_posts.post_title, 
           Min(wp_postmeta.meta_value) AS minprice 
    FROM   wp_postmeta 
           JOIN wp_posts 
             ON wp_postmeta.post_id = wp_posts.id 
    WHERE  wp_posts.post_type = 'Product' 
           AND wp_postmeta.meta_key = '_regular_price' 
    GROUP  BY wp_posts.post_title) AS x 
   INNER JOIN (SELECT wp_postmeta.post_id, 
                      wp_posts.post_title, 
                      wp_postmeta.meta_value 
               FROM   wp_postmeta 
                      JOIN wp_posts 
                        ON wp_postmeta.post_id = wp_posts.id 
               WHERE  wp_posts.post_type = 'Product' 
                      AND wp_postmeta.meta_key = '_regular_price' 
               ORDER  BY wp_posts.post_title, 
                         wp_postmeta.meta_value) AS f 
           ON x.post_title = f.post_title 
              AND f.meta_value = x.minprice 
  GROUP  BY f.post_title
)

DELETE FROM wp_posts WHERE ID NOT IN (

  SELECT Min(f.post_id)
  FROM   (SELECT wp_posts.post_title, 
           Min(wp_postmeta.meta_value) AS minprice 
    FROM   wp_postmeta 
           JOIN wp_posts 
             ON wp_postmeta.post_id = wp_posts.id 
    WHERE  wp_posts.post_type = 'Product' 
           AND wp_postmeta.meta_key = '_regular_price' 
    GROUP  BY wp_posts.post_title) AS x 
   INNER JOIN (SELECT wp_postmeta.post_id, 
                      wp_posts.post_title, 
                      wp_postmeta.meta_value 
               FROM   wp_postmeta 
                      JOIN wp_posts 
                        ON wp_postmeta.post_id = wp_posts.id 
               WHERE  wp_posts.post_type = 'Product' 
                      AND wp_postmeta.meta_key = '_regular_price' 
               ORDER  BY wp_posts.post_title, 
                         wp_postmeta.meta_value) AS f 
           ON x.post_title = f.post_title 
              AND f.meta_value = x.minprice 
  GROUP  BY f.post_title
)

Warning

如果没有先备份您的数据跑起来被人在互联网上给你删除查询。最起码,启动一个事务,运行删除,选择的结果,看看他们,以确保它们是正确的,使用下面的代码模式:

START TRANSACTION;
DELETE FROM ...
DELETE FROM ...
SELECT * FROM ... -/*to check the deletes worked and didn't remove too much*/
ROLLBACK;

更改ROLLBACK承诺,当你快乐

编辑:

Option 1

让元取决于职位的职位(它可能已经做的,保证了级联删除):

ALTER TABLE posts_meta
ADD CONSTRAINT fk_pm FOREIGN KEY (posts_id) REFERENCES posts(id) ON DELETE CASCADE

现在我们对posts表的删除,posts_meta条目也将消失

Option2

运行您删除的帖子表如上文所建议

使用以下查询删除从posts_meta,这并不在职位匹配记录的任何记录:

DELETE FROM posts_meta WHERE post_id IN (select post_id from(
  SELECT pm.post_id 
  FROM
    posts_meta pm
    LEFT JOIN 
    posts p
    ON p.id = pm.post_id
  WHERE
    p.id IS NULL

) i )

该发现ID列表最里面的子查询包裹的另一个子查询是有原因的内部;有些情况下,MySQL将拒绝删除,如果该模式是DELETE FROM x WHERE y IN (SELECT x FROM y)因为你不能修改你从选择表的情况。结束工作的另一个选择是导致MySQL不要把它从你从选择相同的表中删除一个黑客


1
投票

我们的想法是,选择的ID从表wp_postswp_postmeta到临时表postspostmeta删除。即使你从任何表中删除数据这将保留ID的列表。然后,从表wp_posts删除数据和wp_postmeta一个又一个基于ID的在临时表就行了。最后一步是清除临时表(从他们删除数据)。

本次交易以这种方式使用,以允许运行在phpMyAdmin此代码。

代码的优化版本:

BEGIN;

CREATE TEMPORARY TABLE IF NOT EXISTS minPostIds AS 
    SELECT Min(f.post_id)
    FROM   (SELECT wp_posts.post_title, 
               Min(wp_postmeta.meta_value) AS minprice 
        FROM   wp_postmeta 
               JOIN wp_posts 
                 ON wp_postmeta.post_id = wp_posts.id 
        WHERE  wp_posts.post_type = 'Product' 
               AND wp_postmeta.meta_key = '_regular_price' 
        GROUP  BY wp_posts.post_title) AS x 
        INNER JOIN (SELECT wp_postmeta.post_id, 
                          wp_posts.post_title, 
                          wp_postmeta.meta_value 
                   FROM   wp_postmeta 
                          JOIN wp_posts 
                            ON wp_postmeta.post_id = wp_posts.id 
                   WHERE  wp_posts.post_type = 'Product' 
                          AND wp_postmeta.meta_key = '_regular_price') AS f 
               ON x.post_title = f.post_title 
                  AND f.meta_value = x.minprice 
        GROUP  BY f.post_title;


DELETE FROM wp_posts WHERE wp_posts.ID IN (SELECT ID FROM minPostIds);
DELETE FROM wp_postmeta WHERE wp_postmeta.post_id IN (SELECT ID FROM minPostIds); 

DELETE FROM minPostIds;

COMMIT;

这个版本的作品:

BEGIN;

CREATE TEMPORARY TABLE IF NOT EXISTS posts AS 
    SELECT ID
    FROM wp_posts
    WHERE wp_posts.ID NOT IN 
    (
        SELECT Min(f.post_id)
        FROM   (SELECT wp_posts.post_title, 
                   Min(wp_postmeta.meta_value) AS minprice 
            FROM   wp_postmeta 
                   JOIN wp_posts 
                     ON wp_postmeta.post_id = wp_posts.id 
            WHERE  wp_posts.post_type = 'Product' 
                   AND wp_postmeta.meta_key = '_regular_price' 
            GROUP  BY wp_posts.post_title) AS x 
            INNER JOIN (SELECT wp_postmeta.post_id, 
                              wp_posts.post_title, 
                              wp_postmeta.meta_value 
                       FROM   wp_postmeta 
                              JOIN wp_posts 
                                ON wp_postmeta.post_id = wp_posts.id 
                       WHERE  wp_posts.post_type = 'Product' 
                              AND wp_postmeta.meta_key = '_regular_price' 
                       ORDER  BY wp_posts.post_title, 
                                 wp_postmeta.meta_value) AS f 
                   ON x.post_title = f.post_title 
                      AND f.meta_value = x.minprice 
            GROUP  BY f.post_title
);



CREATE TEMPORARY TABLE IF NOT EXISTS postmeta AS     
SELECT post_id
    FROM wp_postmeta
    WHERE wp_postmeta.post_id NOT IN 
    (
        SELECT Min(f.post_id)
        FROM   (SELECT wp_posts.post_title, 
                   Min(wp_postmeta.meta_value) AS minprice 
            FROM   wp_postmeta 
                   JOIN wp_posts 
                     ON wp_postmeta.post_id = wp_posts.id 
            WHERE  wp_posts.post_type = 'Product' 
                   AND wp_postmeta.meta_key = '_regular_price' 
            GROUP  BY wp_posts.post_title) AS x 
            INNER JOIN (SELECT wp_postmeta.post_id, 
                              wp_posts.post_title, 
                              wp_postmeta.meta_value 
                       FROM   wp_postmeta 
                              JOIN wp_posts 
                                ON wp_postmeta.post_id = wp_posts.id 
                       WHERE  wp_posts.post_type = 'Product' 
                              AND wp_postmeta.meta_key = '_regular_price' 
                       ORDER  BY wp_posts.post_title, 
                                 wp_postmeta.meta_value) AS f 
                   ON x.post_title = f.post_title 
                      AND f.meta_value = x.minprice 
            GROUP  BY f.post_title
);


DELETE FROM wp_posts WHERE wp_posts.ID IN (SELECT ID FROM posts);

DELETE FROM wp_postmeta WHERE wp_postmeta.post_id IN (SELECT post_id FROM postmeta);

DELETE FROM posts;
DELETE FROM postmeta;

COMMIT;

您还可以创建一个存储过程:

CREATE PROCEDURE DeleteFromTables()
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS posts 
ENGINE=MyISAM 
AS (
    SELECT ID
    FROM wp_posts
    WHERE wp_posts.ID NOT IN 
    (
        SELECT Min(f.post_id)
        FROM   (SELECT wp_posts.post_title, 
                   Min(wp_postmeta.meta_value) AS minprice 
            FROM   wp_postmeta 
                   JOIN wp_posts 
                     ON wp_postmeta.post_id = wp_posts.id 
            WHERE  wp_posts.post_type = 'Product' 
                   AND wp_postmeta.meta_key = '_regular_price' 
            GROUP  BY wp_posts.post_title) AS x 
            INNER JOIN (SELECT wp_postmeta.post_id, 
                              wp_posts.post_title, 
                              wp_postmeta.meta_value 
                       FROM   wp_postmeta 
                              JOIN wp_posts 
                                ON wp_postmeta.post_id = wp_posts.id 
                       WHERE  wp_posts.post_type = 'Product' 
                              AND wp_postmeta.meta_key = '_regular_price' 
                       ORDER  BY wp_posts.post_title, 
                                 wp_postmeta.meta_value) AS f 
                   ON x.post_title = f.post_title 
                      AND f.meta_value = x.minprice 
            GROUP  BY f.post_title
    )
);



CREATE TEMPORARY TABLE IF NOT EXISTS postmeta
ENGINE=MyISAM 
AS (
    SELECT post_id
    FROM wp_postmeta
    WHERE wp_postmeta.post_id NOT IN 
    (
        SELECT Min(f.post_id)
        FROM   (SELECT wp_posts.post_title, 
                   Min(wp_postmeta.meta_value) AS minprice 
            FROM   wp_postmeta 
                   JOIN wp_posts 
                     ON wp_postmeta.post_id = wp_posts.id 
            WHERE  wp_posts.post_type = 'Product' 
                   AND wp_postmeta.meta_key = '_regular_price' 
            GROUP  BY wp_posts.post_title) AS x 
            INNER JOIN (SELECT wp_postmeta.post_id, 
                              wp_posts.post_title, 
                              wp_postmeta.meta_value 
                       FROM   wp_postmeta 
                              JOIN wp_posts 
                                ON wp_postmeta.post_id = wp_posts.id 
                       WHERE  wp_posts.post_type = 'Product' 
                              AND wp_postmeta.meta_key = '_regular_price' 
                       ORDER  BY wp_posts.post_title, 
                                 wp_postmeta.meta_value) AS f 
                   ON x.post_title = f.post_title 
                      AND f.meta_value = x.minprice 
            GROUP  BY f.post_title 
    )
);


START TRANSACTION;

    DELETE FROM wp_posts
    WHERE wp_posts.ID IN (SELECT ID FROM posts);

    DELETE FROM wp_postmeta
    WHERE wp_postmeta.post_id IN (SELECT post_id FROM postmeta);

COMMIT;

DELETE FROM posts;
DELETE FROM postmeta;
END;
© www.soinside.com 2019 - 2024. All rights reserved.