如果我有两个表:
Users Labels
----- ------
id id
user_id
和用户以及一对多的标签。
我想说的是,“给我所有具有label = 1或label = 2但不包含label = 3的用户”,因此具有标签[1,5,6]的用户将是有效的[2,5,6 ]有效,但[2,3,4]无效。
我将如何去做?我目前正在使用array_agg
和unnest
,但我想在没有数组操作的情况下执行此操作。
WITH (
SELECT user_id, ARRAY_AGG(id) as labels from label
) as labels_agg
SELECT id FROM users
LEFT JOIN labels_agg ON id=user_id
WHERE 1 in UNNEST(labels) and 2 in UNNEST(labels) and 3 not in UNNEST(labels)
答案 0 :(得分:2)
这可以通过not exists
完成。
SELECT l1.user_id, l1.id as labels
from label l1
where id in (1,2)
and not exists (select 1 from label l2 where l1.user_id=l2.user_id and l2.id = 3)
答案 1 :(得分:2)
带有label = 1或label = 2,但没有label = 3
对于这种查询,我建议使用group by
和having
:
select l.user_id
from labels l
where l.id in (1, 2, 3)
group by l.user_id
having sum(case when l.id in (1, 2) then 1 else 0 end) > 0 and
sum(case when l.id in (3) then 1 else 0 end) = 0 ;
带有条件聚合的having
子句非常灵活。 sum(case . . . )
计算每个用户ID提及的标签数。 > 0
说,至少存在一个。 = 0
说不存在。
在这种情况下,您实际上可以将逻辑简化为:
select l.user_id
from labels l
where l.id in (1, 2, 3)
group by l.user_id
having max(l.id) in (1, 2);
这恰好适用于这些id,但不能一概而论。
答案 2 :(得分:2)
您可以使用EXCEPT获得所需的结果。
;WITH cte AS
(
SELECT DISTINCT usr.id AS UserId, lbl.id AS Label_Id FROM Users usr LEFT
JOIN Labels lbl ON
usr.id = lbl.[user_id]
)
SELECT UserId FROM cte WHERE
Label_Id IN (1,2)
EXCEPT
SELECT UserId FROM cte WHERE
Label_Id IN (3)
这是demo
答案 3 :(得分:1)
#standardSQL
SELECT user_id
FROM labels
GROUP BY user_id
HAVING COUNTIF(id IN (1, 2)) > 0
AND COUNTIF(id = 3) = 0