假设我有这张表stuff_property
:
| stuff_id (fk) | property_id |
| ------------- | ----------- |
现在我想进行返回东西及其属性的查询:
SELECT stuff_id
, GROUP_CONCAT(DISTINCT property_id) as property_list
FROM stuff_property
GROUP
BY stuff_id
但是我想只列出具有某些属性的东西,比方说42。我不能简单地添加WHERE property_id = 42
因为然后分组会“失败”而GROUP_CONCAT
不会列出所有属性,只有'42 ”。我能做的最好就是使用嵌套查询,但效率非常低:
SELECT a.stuff_id, GROUP_CONCAT(DISTINCT a.property_id) as property_list
FROM stuff_property a GROUP BY a.stuff_id
WHERE 42 IN
(SELECT b.property_id FROM stuff_property b WHERE b.stuff_id = a.stuff_id)
我想知道如何进行一些后向组引用,所以我可以使查询生效(编写伪代码):
SELECT stuff_id,GROUP_CONCAT(DISTINCT property_id)as property_list FROM stuff_property GROUP BY stuff_id WHERE 42 IN 分组-reference.property_id
有办法吗?
答案 0 :(得分:0)
有三种方法可以做到这一点:
使用子查询(被认为效率最低)
使用加入(更好但效率仍然低)
SELECT stuff_id, GROUP_CONCAT(DISTINCT property_id) as property_list
FROM stuff_property
INNER JOIN (SELECT stuff_ID FROM stuff_property where property_ID = 42) SubSet
GROUP BY stuff_id
使用exists关键字(通常认为效率最高)
SELECT sp.Stuff_ID, GROUP_CONCAT(DISTINCT sp.property_id) as property_list
FROM stuff_property sp
WHERE EXISTS (SELECT 1 FROM stuff_property s
WHERE s.stuff_ID = sp.stuff_Id
and s.property_ID=42);
在存在和连接中,你实质上是在说找到一组具有属性ID的东西。现在返回该子集中所有内容的所有属性。
至于证明效率。这是基于几篇在线文章和我自己的实践经验。但是不要接受我或他们的话。检查所有这三个的执行计划,看看你有什么困扰!
接下来的两个可以工作......
这使用find_in_set来解析用逗号分隔的字符串作为值
SELECT stuff_id, GROUP_CONCAT(DISTINCT property_id) as property_list
FROM stuff_property
WHERE find_in_set('42',GROUP_CONCAT(DISTINCT property_id)) > 0
这也可能有效,但性能开始变得更有问题了。
Select * from (
Select stuff_ID, Group_Concat(Distinct property_ID) as Property_list
FROM stuff_property) B
WHERE find_in_set('42',Property_List) > 0