简体   繁体   English

如何查询表(具有与单个实体相关的多行)并仅在满足所有条件的情况下返回GROUPED结果?

[英]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

  • user_id 用户身份
  • some_key some_key
  • some_value SOME_VALUE

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.

相关问题 是否有一个带有多个where子句的select查询在一个结果表中返回多个结果行? - Have a select query with multiple where clauses return multiple result rows in one result table? MySQL查询返回由一个字段分组的表的所有字段,但仅在该分组在另一个字段中具有多个值的情况下 - MySQL query to return all fields of a table grouped by one field but only where that grouping has more than one value in another field 如果MySQL中未满足“ where”,如何返回具有不同值的行 - How to return row with diffrent value if “where” has not been met in MySQL 如何基于整数数组(ID)仅返回满足所有条件的行? - How do I return only rows where all conditions are met based on an array of intergers (IDs)? 如何构造一个MySql查询,该查询返回具有数组中所有值的结果? - How to frame a MySql query which return result which has all the values in an array? MySQL仅在所有行均为WHERE的值时才返回单行 - MySQL return a single row only when all rows are the value of the WHERE 如何从B表的所有相应行中仅选择A的值都为X的条目? - How to select only entries from A which have only values=X in all respective rows in B table? 如何从左表返回行,其中右表的条件在没有子查询的所有行上为真 - How to return rows from left table where condition on right table true on all row without sub query 插入值具有子查询的表并返回多行 - Insert into table where values have sub queries and return multiple rows 在单个 sql 查询中计算并返回多行并将结果打印为表格 - To count and return multiple row in single sql query and print result as table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM