我有两张桌子
Visitor(id, ...)
和
Tracking(id, visitor_id, field, string_value, boolean_value, string_value, integer_value)
我想返回所有visitors
,以查找与{0}}匹配的每个提供条件的人trackings
。换句话说,对于每个条件,应该有一个匹配它的相应跟踪记录。
visitor
可以包含多个trackings
目前我有以下查询,但当多于1个查询时,它不起作用。
SELECT *
FROM visitors AS v
LEFT JOIN trackings AS t ON t.visitor_id = v.id
WHERE (
v.app_id = '123'
// there can be an arbitrary number of these conditions
AND (t.field = 'admin' AND t.boolean_value)
AND (t.field = 'users_created' AND t.integer_value > 1)
...
AND (t.field = 'username' AND t.string_value = 'jack')
我在考虑为每个条件做一个IF EXISTS
,但是每个条件必须单独执行一个子查询看起来非常昂贵。
有关如何解决这个问题的任何建议吗?
答案 0 :(得分:1)
如果您希望访问者拥有所有跟踪,请使用group by
和having
。这是一个例子:
SELECT v.id
FROM visitors v JOIN
trackings t
ON t.visitor_id = v.id
WHERE v.app_id = '123' AND
( (t.field = 'admin' AND t.boolean_value) OR
(t.field = 'users_created' AND t.integer_value > 1) OR
...
(t.field = 'username' AND t.string_value = 'jack')
)
GROUP BY v.id
HAVING COUNT(*) = <number of conditions>
答案 1 :(得分:1)
如果不希望分组,可能是因为你想要所有列,那么窗口函数可以这样做:
select *
from (
select *,
count (
t.field = 'admin' and t.boolean_value or
t.field = 'users_created' and t.integer_value > 1 or
t.field = 'username' and t.string_value = 'jack'
or null
) over (partition by v.id) = 3 as matched
from
visitors v
inner join
trackings as t on t.visitor_id = v.id
where v.app_id = '123'
) s
where matched