1

次の状況で助けが必要です。

非常に簡略化されたテーブルusers_log

+-----------------+-------------------+
| id | account_nr |    email          |
+-----------------+-------------------+
| 1  | 0000001    |  cust1_@mail.com  |
| 2  | 0000001    |  cust1_@mail.com  |
| 3  | 0000002    |  cust2_@mail.com  |
| 4  | 0000003    |  cust3_@mail.com  |
| 5  | 0000002    |  cust2_@mail.com  |
| 6  | 0000001    |cust1_new@mail.com |
+-----------------+-------------------+
  1. このテーブルには、顧客が複数回表示されることが許可されています。
  2. 顧客は時間の経過とともにメールアドレスを変更できます。古いエントリは更新されません。

ご覧のとおり、アカウント「0000001」が3回表示され、ある時点で彼のメールアドレスが変更されました。

メールアドレスを変更したことのない顧客の結果のみを返すクエリが必要です。さらに、すべての単一エントリが必要なので、何もグループ化されていません。

したがって、顧客「0000002」および「0000003」によるすべてのエントリは、上記の例のクエリの期待される結果になります。

スクリプト言語で複数のループを使用する方法を見つけましたが、使用できるより効率的なクエリがあるので、データベースの負荷を減らすことができるかどうか疑問に思います。これは非常に大規模なデータベースであり、可能な限り最速のクエリが必要です。よろしくお願いします。

PS:データベース構造はこのようになっていて、私には何も変更する方法がありません。

4

2 に答える 2

1

サブクエリの代わりに JOIN を使用したソリューションを次に示します。これは、派生一時テーブルでは使用できないのに対し、JOIN ではインデックスを使用できるため、パフォーマンスが向上することがよくあります。

SELECT ul1.account_nr, ul1.email
FROM users_log ul1
LEFT JOIN users_log ul2
  ON ul2.account_nr = ul1.account_nr
  AND ul2.email <> ul1.email
WHERE ul2.account_nr IS NULL
于 2012-05-30T16:29:42.333 に答える
1
CREATE TABLE users_log (ID INT, account_nr VARCHAR(1000), email VARCHAR(1000))

INSERT INTO users_log VALUES (1,'0000001','cust1_@mail.com');
INSERT INTO users_log VALUES (2,'0000001','cust1_@mail.com');
INSERT INTO users_log VALUES (3,'0000002','cust2_@mail.com');
INSERT INTO users_log VALUES (4,'0000003','cust3_@mail.com');
INSERT INTO users_log VALUES (5,'0000002','cust2_@mail.com');
INSERT INTO users_log VALUES (6,'0000001','cust1_new@mail.com');

SELECT account_nr
     , email
  FROM users_log a
 WHERE NOT EXISTS
       (SELECT *
          FROM users_log b
         WHERE a.email      != b.email
           AND a.account_nr = b.account_nr)

結果:

    ACCOUNT_NR  EMAIL
1   0000002     cust2_@mail.com
2   0000002     cust2_@mail.com
3   0000003     cust3_@mail.com
于 2012-05-30T16:05:05.190 に答える