[英]How to query a table (which has multiple rows pertaining to a single entity) and return GROUPED result but only where all conditionals have been met?
Firstly, pardon the incredibly vague/long question, I'm really not sure how to summarise my query without the full explanation. 首先,请原谅这个令人难以置信的模糊/冗长的问题,我真的不确定在没有完整解释的情况下如何总结我的查询。
Ok, I have a single MySQL table with the format like so 好的,我只有一个MySQL表格,其格式如下
some_table some_table
If you imagine that, for each user, there are multiple rows, for example: 如果您想象每个用户都有多个行,例如:
1 | skill | html
1 | skill | php
1 | foo | bar
2 | skill | html
3 | skill | php
4 | foo | bar
If I want to find all the users who have listed HTML as a skill I can simply do: 如果我想找到所有将HTML列为一项技能的用户,我可以简单地做到:
SELECT user_id
FROM some_table
WHERE some_key = 'skill' AND some_value='html'
GROUP BY user_id
Easy enough. 很简单。 This would give me user ID's 1 and 2.
这将给我用户ID 1和2。
If I want to find all users who have listed HTML or PHP as a skill then I can do: 如果我想找到所有将HTML 或 PHP列为一项技能的用户,那么我可以这样做:
SELECT user_id
FROM some_table
WHERE (some_key = 'skill' AND some_value='html') OR (some_key = 'skill' AND some_value='php')
GROUP BY user_id
This would give me use ID's 1, 2 and 3. 这将使我使用ID的1、2和3。
Now, what I'm struggling to work out is how I can query the same table but this time say "give me all the users who have listed both HTML and PHP as a skill", ie: just user ID 1. 现在,我要努力解决的问题是如何查询同一张表,但是这次说“给我所有同时列出HTML 和 PHP的用户”,即:仅用户ID 1。
Any advice, guidance or links to docs massively appreciated. 任何建议,指导或与文档的链接均受到高度赞赏。
Thanks. 谢谢。
Here's one way: 这是一种方法:
SELECT user_id
FROM some_table
WHERE user_id IN (SELECT user_id FROM some_table where (some_key = 'skill' AND some_value='html'))
AND user_id IN (SELECT user_id FROM some_table where (some_key = 'skill' AND some_value='php'))
I don't know if this is valid for mysql, but should be (works for other db engines): 我不知道这是否对mysql有效,但应该是(适用于其他数据库引擎):
SELECT php.user_id
FROM some_table php, some_table html
WHERE php.user_id = html.user_id
AND php.some_key = 'skill'
AND html.some_key = 'skill'
AND php.some_value = 'php'
AND html.some_value = 'html';
And alternative, by using HAVING statement: 另外,通过使用HAVING语句:
SELECT user_id, count(*)
FROM some_table
WHERE some_key = 'skill'
AND some_value in ('php','html')
GROUP BY user_id
HAVING count(*) = 2;
And a third option is to use inner selects. 第三种选择是使用内部选择。 A slight alternative approach to David's approach:
大卫方法的另一种替代方法:
SELECT user_id FROM some_table
WHERE
some_key = 'skill' AND
some_value = 'html' AND
user_id IN (
SELECT user_id FROM some_table
WHERE
some_key = 'skill' AND
some_value = 'php' AND
user_id IN (
SELECT user_id FROM some_table
WHERE
some_key = 'skill' AND
some_value = 'js' -- AND user_id IN ... for next level, etc.
)
);
... idea is that you can "pipe" the inner selects. ...想法是您可以“管道”内部选择。 With each new property you add new inner select to the most inner one.
对于每个新属性,您都将向最内部的属性添加新的内部选择。
you need to use a nested query (or a self join, which is different) 您需要使用嵌套查询(或自我连接,这是不同的)
I set up the following table. 我设置了下表。
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| type | char(10) | YES | | NULL | |
| value | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
inserted the following values 插入以下值
+------+-------+-------+
| id | type | value |
+------+-------+-------+
| 1 | skill | html |
| 1 | skill | php |
| 2 | skill | html |
| 3 | skill | php |
| 2 | skill | php |
+------+-------+-------+
ran this query 运行此查询
select id
from test
where type = 'skill'
and value = 'html'
and id in (
select id
from test
where type = 'skill'
and value = 'php');
and got 并得到
+------+
| id |
+------+
| 1 |
| 2 |
+------+
a self join would be as follows 一个自我加入如下
select e1.id
from test e1, test e2
where e1.id = e2.id
and e2.type = 'skill'
and e2.value = 'html'
and e1.type = 'skill'
and e1.value = 'php'
;
and produce the same result. 并产生相同的结果。
so there you have two ways to try it in your code. 因此,您可以通过两种方法在代码中进行尝试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.