2

特定の日付までにレコードを消去するために必要な次のサンプル データがあります。この例では、2012 年 3 月より古いものを使用して、他の関連レコードと一緒に削除する必要があります。

著者テーブル

    Author       Book     date
-------------------------------------
    Smith        Bk1      01/01/2012
    Smith        Bk2      02/01/2012
    Smith        Bk3      02/25/2012
    Johnson      Bk1      06/01/2011
    Johnson      Bk2      09/01/2011
    Johnson      Bk3      03/01/2012
    Johnson      Bk4      01/01/2013
    Jones        BK1      01/01/2001
    Jones        BK2      01/01/2002
    Jones        BK3      01/01/2009
    Jones        BK4      08/01/2013

ブックテーブルもあります

    Author       Book     info
-------------------------------------
    Smith        Bk1      asdfadf
    Smith        Bk2      asdfasdf
    Smith        Bk3      asdfadf
    Johnson      Bk1      asdfadf
    Johnson      Bk2      adsfasdf
    Johnson      Bk3      asdasdf
    Johnson      Bk4      asdfasdf
    Jones        BK1      asdfasdf
    Jones        BK2      adsfasdf
    Jones        BK3      adsfasdf
    Jones        BK4      adsfasdf

上はデータセットです。そのため、著者のテーブルに 2013 年 3 月 1 日より古い本がある場合、すべてのレコードを削除する必要があります。指定された日付よりも新しい本が少なくとも 1 つある場合、すべての記録が保持されます。このシナリオでは、テーブル データ セットに保持されるのは Jones レコードだけです。フィルター処理された Author を特定したら、Book テーブルからレコードを削除し、次に Author テーブルからレコードを削除します。

助けてくれてありがとう、感謝します。

4

2 に答える 2

2

これはあなたが望むことをしているようです(TempDBを使用して概念実証を提供するコードを追加しました):

USE tempdb;

/* Create the same tables, and insert test data */
CREATE TABLE Authors
(
    Author nvarchar(255)
    , Book nvarchar(255)
    , BookDate datetime
);

INSERT INTO Authors VALUES ('joe','book1',GetDate()-100); --100 days old
INSERT INTO Authors VALUES ('joe','book2',GetDate()-200); --200 days old
INSERT INTO Authors VALUES ('joe','book3',GetDate()-300); --300 days old
INSERT INTO Authors VALUES ('sam','book4',GetDate()-400); --etc
INSERT INTO Authors VALUES ('sam','book5',GetDate()-500);
INSERT INTO Authors VALUES ('sam','book6',GetDate()-600);

CREATE TABLE Books
(
    Author nvarchar(255)
    , Book nvarchar(255)
    , Info nvarchar(255)
);

INSERT INTO Books VALUES ('joe','book1','asdf');
INSERT INTO Books VALUES ('joe','book2','asdfg');
INSERT INTO Books VALUES ('joe','book3','asdfh');
INSERT INTO Books VALUES ('sam','book4','asdf');
INSERT INTO Books VALUES ('sam','book5','bsdf');
INSERT INTO Books VALUES ('sam','book6','csdf');

/* This statement deletes rows from the dependent table, Books */
DELETE  
FROM Books 
FROM Books LEFT JOIN 
(       /* This selects all Authors with books in the past 300 days */
    SELECT Author 
    FROM Authors
    WHERE BookDate >= GetDate()-300 
) t2 ON Books.Author = t2.Author
WHERE t2.Author IS NULL; /* This ensures rows from Books only get deleted
                                when for Authors that DON'T have books in the
                                past 300 days */

/* This statement deletes rows from the main table, Authors */
DELETE  
FROM Authors 
FROM Authors LEFT JOIN 
(       /* This selects all Authors with books in the past 300 days */
    SELECT Author 
    FROM Authors
    WHERE BookDate >= GetDate()-300 
) t2 ON Authors.Author = t2.Author
WHERE t2.Author IS NULL; /* This ensures rows from Books only get deleted
                                when for Authors that DON'T have books in the
                                past 300 days */

SELECT * FROM Books;
SELECT * FROM Authors;

Sam の行だけが削除されます。Sam は作成後 300 日より新しい本を持っていない唯一の著者であるためです。

于 2013-09-18T22:20:19.997 に答える
1

最初にテーブル 1 から削除します。

DELETE FROM Table1
WHERE Author NOT IN (SELECT DISTINCT Author 
   FROM Table1 WHERE Date >= '2013-03-01')

次に、表 2 から:

DELETE FROM Table2 WHERE Author NOT IN (SELECT Author FROM Table1)

私がこれまでに書いた SQL の中で最も美しいとは言えませんが、それで十分です。外部キーを持つ正規化されたテーブルがある場合、このようなことは機能しませんが、現在はそうではないと思います。

逆の順序で実行することを主張する場合:

DELETE FROM Table2 WHERE Author NOT IN (
    SELECT DISTINCT Author 
    FROM Table1 WHERE Date >= '2013-03-01')

DELETE FROM Table1
    WHERE Author NOT IN (SELECT DISTINCT Author FROM Table2)
于 2013-09-18T22:23:06.977 に答える