状況
私の目標は、年齢に基づいてデータベースから特定のデータを削除する年 1 回の cronjob を持つことです。私の処分では、Bash と MySQL の力があります。私は bash スクリプトの作成から始めましたが、1 つの SQL クエリだけですべてを実行できるのではないかと思いました。
私は本質的にプログラマーであり、データ構造の経験があまりないため、助けが必要です。
テーブル/データ構造
このクエリに関連するテーブルと列は次のとおりです。
登録:
+-----+-------------------+
| Id | Registration_date |
+-----+-------------------+
| 2 | 2011-10-03 |
| 3 | 2011-10-06 |
| 4 | 2011-10-07 |
| 5 | 2011-10-07 |
| 6 | 2011-10-10 |
| 7 | 2011-10-13 |
| 8 | 2011-10-14 |
| 9 | 2011-10-14 |
| 10 | 2011-10-17 |
+-------------------------+
関連付けられたクライアント:
+-----------+-----------------+
| Client_id | Registration_id |
+-----------+-----------------+
| 2 | 2 |
| 3 | 2 |
| 3 | 4 |
| 4 | 5 |
| 3 | 6 |
| 5 | 6 |
| 3 | 8 |
| 8 | 9 |
| 7 | 10 |
+-----------------------------+
クライアント: ここでは ID のみが関連します。
ご覧のとおり、これは単純な多対多の関係です。クライアントは自分の名前に対して複数の登録を持つことができ、登録は複数のクライアントを持つことができます。
目標
5 年間新規登録していないクライアントのすべての登録とクライアント データを削除する必要があります。シンプルですね。
トリッキーな部分
特定のクライアントからの登録に関する他のクライアントが 5 年以内に新しい登録を行った場合、データを保持する必要があります。
したがって、クライアント A が 4 つの登録を持ち、その中に彼だけがいて、1 つの登録が彼自身とクライアント B であると想像してください。5 つの登録はすべて 5 年以上前のものです。クライアント B が 5 年間新規登録をしていない場合、クライアント A の登録と記録のすべてを削除する必要があります。Bが5 年以内に新しい登録を行った場合、クライアント A のすべてのデータは、彼自身の古い登録を含めて保持する必要があります。
私が試したこと
私のクエリを構築して、私はこれまでのところ得ました:
DELETE * FROM `Registration` AS Reg
WHERE TIMESTAMPDIFF(YEAR, Reg.`Registration_date`, NOW()) >= 5
AND
(COUNT(`Id`) FROM `Registration` AS Reg2
WHERE Reg2.`Id` IN (SELECT `Registration_id` FROM `AssociatedClient` AS Clients
WHERE Clients.`Client_id` IN (SELECT `Client_id` FROM `AssociatedClient` AS Clients2
WHERE Clients2.`Registration_id` IN -- stuck
#I need all the registrations from the clients associated with the first
# (outer) registration here, that are newer than 5 years.
) = 0 -- No newer registrations from any associated clients
私はSQLの経験が非常に限られていることを理解してください。これまでに得たものでさえ、(結合などを使用して)大幅に最適化でき、正しくない場合さえあることに気付きました。
私が行き詰まった理由は、ある種のループを使用できれば、私が念頭に置いていた解決策が機能するためであり、これはこの種の SQL クエリで簡単に実行できるものではないことに気付きました。
どんな助けでも
とても感謝しています。