如果列表是另一个列表的子集,则 sql 中的 Select 行

Select rows in sql if list is a subset of another list

我在 Books-CommunityBooks-User 之间有两个多对多映射 table。 当我将 UserId 传递给存储过程时,如何获取用户书籍中存在的所有社区?

用户书籍Table

[UserId]----------------------------[BookId]

fd95eff5-394e-4d51-b1af-46723268485f----27

fd95eff5-394e-4d51-b1af-46723268485f----28

fd95eff5-394e-4d51-b1af-46723268485f----35

fd95eff5-394e-4d51-b1af-46723268485f----36

fd95eff5-394e-4d51-b1af-46723268485f----40

fd95eff5-394e-4d51-b1af-46723268485f----41

fd95eff5-394e-4d51-b1af-46723268485f----56

fd95eff5-394e-4d51-b1af-46723268485f----67

fd95eff5-394e-4d51-b1af-46723268485f----88

fd95eff5-394e-4d51-b1af-46723268485f----103

fd95eff5-394e-4d51-b1af-46723268485f----104

fd95eff5-394e-4d51-b1af-46723268485f----155

fd95eff5-394e-4d51-b1af-46723268485f----156

BooksCommunityMap

[BookId]-----[CommunityId]

29-----------23

30-----------23

32-----------23

34-----------23

35-----------23

36-----------23

我想select所有的社区,它的所有书都存在于用户的书中

;WITH cte as
(
     SELECT UserID, CASE WHEN BookId IN (SELECT Id From @incomingTableValuedVariable) THEN 0 ELSE 1 END as NoBook
     FROM MAPTABLE 
),
cte2 as
(
     SELECT UserID, MAX(NOBook) as NoBook
     FROM cte 
     GROUP BY UserId
)
SELECT UserID
FROM cte2
WHERE NoBook = 0;

在这里您可以了解 using a Table-Valued Parameters。我给你一个查询的例子来得到你需要的东西:

DECLARE @tvv TABLE (id int)

INSERT INTO @tvv VALUES
(1),
(2)

;WITH users_books AS (
SELECT *
FROM (VALUES
(1,1),(2,1),(3,1),
(1,2),(2,2),(3,3),
(1,3),(2,3),(3,5),
(1,4),(2,4),(3,7),
      (2,5),(3,8),
      (2,6),(3,9)
) as t (UserID, BookID)
)

SELECT UserID
FROM users_books u
LEFT JOIN @tvv i 
    ON i.id = u.BookID
GROUP BY UserID
HAVING COUNT(id) = (SELECT COUNT(*) FROM @tvv)

输出:

UserID
-----------
1
2

(2 row(s) affected)