Jul*_*n L 11 sqlite query subquery
我正在寻找一种创建查询以执行以下操作的方法:
让我们考虑 3 个表:
让我们考虑每个表的这种结构:
产品:
标签:
标签关系:
我想要的是:
例如,获取所有标记为标签 id 10、11 和 12 的产品。
此查询不起作用,因为它返回至少具有以下标签之一的产品:
select
p.name as name,
p.id as id
from
products p inner join tag_ties ties
on
p.id=ties.ref_id
where
ties.ref_id=p.id and
ties.tag_id in (10,11,12)
group by
p.id
order by
p.name asc
Run Code Online (Sandbox Code Playgroud)
小智 12
您可以使用 intersect 语句解决此问题。为每个 tag_id 做一个单独的选择,并用 intersects 将它们连接起来,你只会得到匹配所有三个 tag_id 的记录。
select products.id, products.name from
products join tag_ties
on tag_ties.ref_id = products.id
where tag_ties.tag_id = 10
intersect
select products.id, products.name from
products join tag_ties
on tag_ties.ref_id = products.id
where tag_ties.tag_id = 11
intersect
select products.id, products.name from
products join tag_ties
on tag_ties.ref_id = products.id
where tag_ties.tag_id = 12
Run Code Online (Sandbox Code Playgroud)
您还可以使用临时视图使这看起来更好一些。
create temporary view temp_view as
select name, products.id as id, tag_ties.tag_id as tag_id
from products join tag_ties
on tag_ties.ref_id = products.id
select name, id from temp_view where tag_id = 10
intersect ...
Run Code Online (Sandbox Code Playgroud)
dab*_*st1 10
尝试这样的事情:
select
t1.id,
t1.name
from
(
select
p.name as name,
p.id as id
from
products p inner join tag_ties ties
on
p.id=ties.ref_id
where
ties.tag_id in (10,11,12)
) as t1
group by
t1.id,
t1.name
having
count(t1.id) = 3
order by
t1.name asc
;
Run Code Online (Sandbox Code Playgroud)
不需要来自所选答案的子查询。要选择具有所有给定标签 ID 的产品,查询可以很简单:
SELECT
p.*
FROM
products AS p
INNER JOIN
tag_ties AS tt
ON
tt.ref_id = p.id
AND
tt.tag_id IN (10, 11, 12)
GROUP BY
p.id
HAVING
COUNT(p.id)=3
Run Code Online (Sandbox Code Playgroud)
扩展这个想法,我们还可以在单次拍摄中基于标签标签进行查询。选择带有标签的产品('foo', 'bar', 'baz'):
SELECT
p.*
FROM
products AS p
INNER JOIN
tags AS t
ON
t.label IN ('foo', 'bar', 'baz')
INNER JOIN
tag_ties AS tt
ON
tt.ref_id = p.id
AND
tt.tag_id = t.id
GROUP BY
p.id
HAVING
COUNT(p.id)=3
Run Code Online (Sandbox Code Playgroud)
为了稍微复杂一点,我们可以使用子查询来混合交集 ( AND) 和联合 ( OR)。下面的查询将返回带有组的所有标签和组('foo', 'bar')的至少一个标签的产品('baz', 'ding'):
SELECT
p.*
FROM
(
SELECT
p.*
FROM
products AS p
INNER JOIN
tags AS t
ON
t.label IN ('foo', 'bar')
INNER JOIN
tag_ties AS tt
ON
tt.ref_id = p.id
AND
tt.tag_id = t.id
GROUP BY
p.id
HAVING
COUNT(p.id)=2
) AS p
INNER JOIN
tags AS t
ON
t.label IN ('baz', 'ding')
INNER JOIN
tag_ties AS tt
ON
tt.ref_id = p.id
AND
tt.tag_id = t.id
GROUP BY
p.id
Run Code Online (Sandbox Code Playgroud)