2

まず、質問を読んだ後、誰かがこの質問のより有益なタイトルについて提案を持っている場合は、私が今、ビジネスにいくらか欠けていると思うので、教えてください...

このテーブル構造を考えると:

+---------+-------------------------------------+------+-----+---------+----------------+
| Field   | Type                                | Null | Key | Default | Extra          |
+---------+-------------------------------------+------+-----+---------+----------------+
| id      | int(11)                             | NO   | PRI | NULL    | auto_increment |
| account | varchar(20)                         | YES  | UNI | NULL    |                |
| domain  | varchar(100)                        | YES  |     | NULL    |                |
| status  | enum('FAILED','PENDING','COMPLETE') | YES  |     | NULL    |                |
+---------+-------------------------------------+------+-----+---------+----------------+

そしてこのデータ:

+----+---------+------------------+----------+
| id | account | domain           | status   |
+----+---------+------------------+----------+
|  1 | jim     | somedomain.com   | COMPLETE |
|  2 | bob     | somedomain.com   | COMPLETE |
|  3 | joe     | somedomain.com   | COMPLETE |
|  4 | frank   | otherdomain.com  | COMPLETE |
|  5 | betty   | otherdomain.com  | PENDING  |
|  6 | shirley | otherdomain.com  | FAILED   |
|  7 | tom     | thirddomain.com  | FAILED   |
|  8 | lou     | fourthdomain.com | COMPLETE |
+----+---------+------------------+----------+

すべてのアカウント(行)に対して「COMPLETE」ステータスを持つすべてのドメインを選択したいと思います。

ステータスが「COMPLETE」以外の値を含む行を持つドメインは返さないでください。

したがって、上記の例では、期待される結果は次のようになります。

+------------------+
| domain           |
+------------------+
| somedomain.com   |
| fourthdomain.com |
+------------------+

明らかに、次のようなサブクエリを使用してこれを実現できます。

mysql> select distinct domain from test_table where status = 'complete' and domain not in (select distinct domain from test_table where status != 'complete'); 
+------------------+
| domain           |
+------------------+
| somedomain.com   |
| fourthdomain.com |
+------------------+
2 rows in set (0.00 sec)

これは私たちの小さなモックアップテストテーブルではうまく機能しますが、実際の状況では、問題のテーブルは数万(または数十万)の行になります。もっと効率的な方法があるかどうか知りたいです。これは、サブクエリが遅くて集中的であるためです。

4

2 に答える 2

2

これはどう:

select domain
from   test_table
group by domain
having sum(case when status = 'COMPLETE'
                then 0 else 1 end) = 0
于 2013-03-25T13:57:10.547 に答える
0

これでうまくいくと思います。事実上、2つの基本的なクエリを結合して、それらの数を比較するだけです。

select
    main.domain
from 
    your_table main

    inner join 
    (
        select 
            domain, count(id) as cnt
        from 
            your_table
        where 
            status = 'complete'
        group by 
            domain
    ) complete
    on complete.domain = main.domain

group by
    main.domain

having
    count(main.id) = complete.cnt

domainまた、これはその列の結合に依存しているため、インデックスがオンになっていることを確認する必要があります。

于 2013-03-25T14:00:26.530 に答える