有这些表格:
customers
---------------------
`id` smallint(5) unsigned NOT NULL auto_increment,
`name` varchar(100) collate utf8_unicode_ci default NOT NULL,
....
customers_subaccounts
-------------------------
`companies_id` mediumint(8) unsigned NOT NULL,
`customers_id` mediumint(8) unsigned NOT NULL,
`subaccount` int(10) unsigned NOT NULL
我需要让所有为同一家公司分配了多个子帐户的客户。
这就是我所拥有的:
SELECT * FROM customers
WHERE id IN
(SELECT customers_id
FROM customers_subaccounts
GROUP BY customers_id, companies_id
HAVING COUNT(subaccount) > 1)
但是这个查询太慢了。如果我将 DISTINCT 修饰符添加到子查询的SELECT中的 customers_id ,它最后会检索整个查询的相同客户列表,这样会更慢。也许有更好的方式没有subquerying,任何更快的东西都会有所帮助,而且我不确定它是否会检索到准确的正确列表。
任何帮助?
答案 0 :(得分:4)
您可以使用INNER JOIN
:
SELECT t1.id
FROM customers t1
INNER JOIN
(
SELECT DISTINCT customers_id
FROM customers_subaccounts
GROUP BY customers_id, companies_id
HAVING COUNT(*) > 1
) t2
ON t1.id = t2.customers_id
答案 1 :(得分:2)
您也可以尝试使用EXISTS()
,这可能比加入更快:
SELECT * FROM customers t
WHERE EXISTS(SELECT 1 FROM customers_subaccounts s
WHERE s.customers_id = t.id
GROUP BY s.customers_id, s.companies_id
HAVING COUNT(subaccount) > 1)
您还应考虑添加以下索引(如果尚未存在):
customers_subaccounts (customers_id,companies_id,subaccount)
customers (id)
答案 2 :(得分:2)
假设你想为公司提供不同的子帐户(或者保证它们不同),那么在某些情况下,以下内容会更快:
select c.*
from (select distinct cs.customers_id
from customers_subaccounts cs join
customers_subaccounts cs2
on cs.customers_id = cs2.customers_id and
cs.companies_id = cs2.companies_id and
cs.subaccount < cs2.subaccount
) cc join
customers c
on c.customers_id = cc.customers_id;
特别是,这可以利用customers_subaccounts(customers_id, companies_id, subaccount)
上的索引。
注意:这假设subaccounts
对于您想要的行是不同的。真正需要的是一种在customers_subaccounts
表中定义唯一行的方法。
答案 3 :(得分:1)
尝试以下内容;)
SELECT DISTINCT t1.*
FROM customers t1
INNER JOIN customers_subaccounts t2 ON t1.id = t2.customers_id
GROUP BY t1.id, t1.name, t2.companies_id
HAVING COUNT(t2.subaccount) > 1
您也可以在index
上添加customers_id
。
答案 4 :(得分:1)
有一种方法可以通过使用缓存子查询结果来加速查询。您的查询感知mysql的一个简单更改,可以缓存子查询结果:
SELECT * FROM customers
WHERE id IN
(select * from
(SELECT distinct customers_id
FROM customers_subaccounts
GROUP BY customers_id, companies_id
HAVING COUNT(subaccount) > 1) t1);
我多年前就用它了,它对我很有帮助。