mysql-选择不同的互斥(基于另一列的值)行
首先,我想说的是,如果在阅读了这个问题后,有人对这个问题有一个更具信息性的标题的建议,请告诉我,因为我认为我的有点缺乏,现在,谈正事吧 鉴于此表结构:mysql-选择不同的互斥(基于另一列的值)行,mysql,sql,Mysql,Sql,首先,我想说的是,如果在阅读了这个问题后,有人对这个问题有一个更具信息性的标题的建议,请告诉我,因为我认为我的有点缺乏,现在,谈正事吧 鉴于此表结构: +---------+-------------------------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra
+---------+-------------------------------------+------+-----+---------+----------------+
| 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 |
+----+---------+------------------+----------+
我想为所有帐户(行)选择具有“完成”状态的所有域
任何具有包含状态为“完成”以外的任何值的行的域都不得返回
在上面的例子中,我的预期结果是:
+------------------+
| 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)
这在我们的小模型测试表上可以很好地工作,但在实际情况中,所讨论的表将有数十(甚至数百)行,我很好奇是否有更有效的方法来实现这一点,因为子查询既慢又密集。这是怎么回事:
select domain
from test_table
group by domain
having sum(case when status = 'COMPLETE'
then 0 else 1 end) = 0
我想这会管用的。实际上只是将两个基本查询连接在一起,然后比较它们的计数
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
您还应该确保在
域上有索引,因为这依赖于该列上的联接。太棒了!这正是我所需要的。请在你的回答中看到我的评论。+1显然执行v。嗯,而且是甜的/简单的引导。不错。虽然这个方法的性能确实比子查询好,但我选择了另一个答案,因为它的性能比这个好得多。在一个有10k行的表上,您的查询在5.56秒内完成了该操作,而另一个答案花费了0.11秒。@jesse_galley对此错误表示抱歉-是在文本编辑器中手工编写的。足够公平的重新性能,看起来mySql必须在最终结果的每一行上快速实现案例
。。。或者做一些聪明的优化。我现在已经简化了,所以不知道你是否有兴趣再检查一遍。虽然不确定它是否会更快,但可能值得快速检查一下。但绝对不能与另一个答案相匹配,因为它的简单甜美!祝你好运+顺便提一下,我想问你一个问题。问得好。