SQL,只有匹配所有外键值才能返回记录?

时间:2012-04-11 09:21:45

标签: sql sql-server sql-match-all relational-division

我有两张桌子

Table A
type_uid, allowed_type_uid
9,1
9,2
9,4
1,1
1,2
24,1
25,3

Table B
type_uid
1
2

从表A我需要返回

9
1

使用WHERE IN子句我可以返回

9
1
24

3 个答案:

答案 0 :(得分:3)

SELECT
  TableA.type_uid
FROM
  TableA
INNER JOIN
  TableB
    ON TableA.allowed_type_uid = TableB.type_uid
GROUP BY
  TableA.type_uid
HAVING
  COUNT(distinct TableB.type_uid) = (SELECT COUNT(distinct type_uid) FROM TableB)

加入两个表togeter,以便您只拥有与您感兴趣的类型相匹配的记录。

将结果集分组为TableA.type_uid

检查每个组的allowed_type_uid值是否与TableB.type_uid中存在的distinct值相同。

如果两个表中都有重复记录,则

distinct只需要 。如果 两个 表都知道只有唯一值,则可以删除{{1}}。


还应该注意,随着TableA的大小增加,这种类型的查询将很快降低性能。这是因为索引在这里实际上没什么帮助。

它仍然可以是一个有用的结构,但不是我建议实时运行查询的结构。而是使用它来创建另一个持久/缓存的结果集,并仅在需要时使用它来刷新这些结果。

答案 1 :(得分:1)

或稍微便宜的版本(资源明智):

SELECT 
    Data.type_uid
FROM 
    A AS Data
    CROSS JOIN
    B
    LEFT JOIN
    A
    ON Data.type_uid = A.type_uid AND B.type_uid = A.allowed_type_uid
GROUP BY 
    Data.type_uid
HAVING 
    MIN(ISNULL(A.allowed_type_uid,-999)) != -999

答案 2 :(得分:0)

你的解释不是很清楚。我想你想从表A中获取那些type_uid,其中表B中的所有记录都有匹配的A.Allowed_type_uid。

SELECT T2.type_uid
FROM (SELECT COUNT(*) as AllAllowedTypes FROM #B) as T1,
    (SELECT #A.type_uid, COUNT(*) as AllowedTypes
    FROM #A
        INNER JOIN #B ON
            #A.allowed_type_uid = #B.type_uid
    GROUP BY #A.type_uid
    ) as T2
WHERE T1.AllAllowedTypes = T2.AllowedTypes

(Dems,你比我快:))