MYSQL选择具有所有必需交叉引用值的行

时间:2018-02-20 20:07:48

标签: mysql sql

我的表A包含唯一ID和一些值

A
+----+-----------+-----------+-----------+-----------+
| ID | X         | Y         | X         | ...       |
+----+-----------+-----------+-----------+-----------+
| 1  | dummyData | dummyData | dummyData | dummyData |
+----+-----------+-----------+-----------+-----------+
| 2  | dummyData | dummyData | dummyData | dummyData |
+----+-----------+-----------+-----------+-----------+

我的表B包含来自A的ID和标记值(varchar)

两个字段的每个组合都保证是唯一的

B
+----+-------+
| ID | Tag   |
+----+-------+
| 1  | TAG_A |
+----+-------+
| 1  | TAG_B |
+----+-------+
| 1  | TAG_C |
+----+-------+
| 2  | TAG_A |
+----+-------+
| 3  | TAG_B |
+----+-------+

我有一个存储过程,它返回给定报告所需的标记

Exec SpGetTagsForReport
+-------+
| Tag   |
+-------+
| TAG_A |
+-------+
| TAG_B |
+-------+

我需要的是从表A中选择所有行,其中存储过程调用中的每个标记都有一个表B条目。

在这种情况下,我应该只返回表A中的第1行

我的第一个想法是选择与存储的proc响应相匹配的每个表B行

SELECT * INTO #reportTags FROM (Exec SpGetTagsForReport)

SELECT * INTO #matchingTags FROM B WHERE Tag IN (SELECT Tag FROM #reportTags )

然后分组并比较计数

SELECT * FROM A 
WHERE ID IN (SELECT ID 
         FROM #matchingTags 
         GROUP BY ID 
         HAVING COUNT(Tag) = (SELECT COUNT(*) FROM reportTags)
        )

我的问题是,这是一条值得走下去的道路吗,还是我错过了一些非常明显的SQL功能,这些功能使得这个微不足道和/或只需要一个声明?

1 个答案:

答案 0 :(得分:1)

我告诉您,您有一张表ReportTags,其中包含报告所需的唯一标记。

您有一张表B,其中包含从idtag的映射。您可以使用group byhaving

获得所需内容
select b.id
from b join
     reporttags rt
     on b.tag = rt.tag
group by b.id
having count(*) = (select count(*) form reporttags);