【发布时间】:2012-03-25 16:56:23
【问题描述】:
大家好,stackoverflow 社区的各位!我已经访问这个网站多年了,这是我的第一篇文章
假设我有一个包含三个表的数据库:
- 组(GroupID、GroupType、max1、大小)
- 糖果(candyID,name,selected)
- 成员(组 ID、名称 ID)
示例:糖果工厂。
在糖果工厂里,80 种不同的糖果生产了 10 种糖果袋。
所以:有 10 种独特的组类型(包),具有 3 种不同的大小:(4、5、6);一组是 80 种独特糖果的组合。
据此,我创建了一个数据库,(有一些关于哪些糖果组合进入组的规则)。
此时我有一个包含 40791 个独特糖果袋的数据库。
现在我想将糖果集合与 DB 中的所有糖果袋进行比较,因此我希望 DB 中缺少 3 个或更少糖果的袋子与比较集合。
-- restore candy status
update candies set selected = 0, blacklisted = 0;
-- set status for candies to be selected
update candies set selected = 1 where name in ('candy01','candy02','candy03','candy04');
select groupId, GroupType, max, count(*) as remainingNum, group_concat(name,', ') as remaining
from groups natural join members natural join candies
where not selected
group by groupid having count(*) <= 3
UNION -- Union with groups which dont have any remaining candies and have a 100% match
select groupid, GroupType, max, 0 as remainingNum, "" as remaining
from groups natural join members natural join candies
where selected
group by groupid having count(*) =groups.size;
上面的查询就是这样做的。但我想要完成的事情是在没有联合的情况下做到这一点,因为速度至关重要。而且我是 sql 新手,非常渴望学习/了解新方法。
你好,罗格
【问题讨论】:
-
不要更新您的数据库来进行选择。它根本不可扩展(两个用户如何同时进行选择?)并且会降低性能,因为写入比读取慢。另请注意,UNION 或尤其是 UNION ALL 通常非常快,并且通常胜过更复杂的单个查询。
-
您的示例架构有问题,因为没有什么可以加入
groups或members到candies所以它将进行交叉连接,除非members.memberID应该是members.candyID