繁体   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?

首先,请原谅这个令人难以置信的模糊/冗长的问题,我真的不确定在没有完整解释的情况下如何总结我的查询。

好的,我只有一个MySQL表格,其格式如下

some_table

  • 用户身份
  • some_key
  • SOME_VALUE

如果您想象每个用户都有多个行,例如:

1   |  skill   |   html
1   |  skill   |   php
1   |  foo     |   bar
2   |  skill   |   html
3   |  skill   |   php
4   |  foo     |   bar

如果我想找到所有将HTML列为一项技能的用户,我可以简单地做到:

SELECT user_id
FROM some_table
WHERE some_key = 'skill' AND some_value='html'
GROUP BY user_id

很简单。 这将给我用户ID 1和2。

如果我想找到所有将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

这将使我使用ID的1、2和3。

现在,我要努力解决的问题是如何查询同一张表,但是这次说“给我所有同时列出HTML PHP的用户”,即:仅用户ID 1。

任何建议,指导或与文档的链接均受到高度赞赏。

谢谢。

这是一种方法:

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'))

我不知道这是否对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';

另外,通过使用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;

第三种选择是使用内部选择。 大卫方法的另一种替代方法:

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.
           )
    );

...想法是您可以“管道”内部选择。 对于每个新属性,您都将向最内部的属性添加新的内部选择。

您需要使用嵌套查询(或自我连接,这是不同的)

我设置了下表。

+-------+----------+------+-----+---------+-------+
| Field | Type     | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id    | int(11)  | YES  |     | NULL    |       |
| type  | char(10) | YES  |     | NULL    |       |
| value | char(10) | YES  |     | NULL    |       |
+-------+----------+------+-----+---------+-------+

插入以下值

+------+-------+-------+
| id   | type  | value |
+------+-------+-------+
|    1 | skill | html  |
|    1 | skill | php   |
|    2 | skill | html  |
|    3 | skill | php   |
|    2 | skill | php   |
+------+-------+-------+

运行此查询

select id 
from test 
where type = 'skill' 
and value = 'html' 
and id in (
select id 
from test 
where type = 'skill' 
and value = 'php');

并得到

+------+
| id   |
+------+
|    1 |
|    2 |
+------+

一个自我加入如下

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'
;

并产生相同的结果。

因此,您可以通过两种方法在代码中进行尝试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM