我有两个表类别和设备,它们具有一对多关系。
Category:
- id
- name
Device:
- id
- category_id
- brand
如果我想使用设备检索所有类别,则可以轻松地将这两个表合并在一起。
SELECT c.*, d.* FROM Category c INNER JOIN Device d ON d.category_id = c.id
问题是我也需要按brand
进行过滤。
假设我有一个类别,并且该类别有3个设备。 现在,我想获得所有设备的所有类别,其中许多设备(按特定类别)中至少有一个品牌的品牌值为 foo 。
如果至少有一个设备与此品牌相匹配,那么我需要退回所有设备。如果没有匹配项,那么我需要返回空结果(没有类别,也没有设备)。
我尝试了以下查询,但似乎无法正常工作。
SELECT c.*, d.*
FROM Category c
INNER JOIN Device d ON d.category_id = c.id
WHERE EXISTS (SELECT * FROM Device d WHERE brand = 'foo')
问题是应该为每个类别执行此WHERE EXISTS
。
有帮助吗?
答案 0 :(得分:1)
您需要correlation
:
select c.*, d.*
from Category c inner join
Device d
on d.category_id = c.id
where exists (select 1
from Device d1
where d1.category_id = c.id and d1.brand = 'foo'
);
答案 1 :(得分:0)
您可以多次加入一个表;一个过滤,一个获取数据
SELECT DISTINCT
cat.*
, devData.*
FROM Device AS devFilter
INNER JOIN Category AS cat
ON devFilter.category_id = cat.id
LEFT JOIN Device AS devData
ON devData.category_id = cat.id
WHERE devFilter.Brand = 'foo'
使用少量到中等的数据集就可以了。如果DISTINCT降低了性能,那么我建议嵌套,以便从devFilter仅返回1个设备,然后再次加入。
SELECT
cat.*
, dev.*
FROM
(
SELECT DISTINCT devFilter.category_id
FROM Device AS devFilter
WHERE devFilter.Brand = 'foo'
) AS categoriesWithBrand
LEFT JOIN Device AS dev
ON dev.category_id = categoriesWithBrand.category_id
LEFT JOIN Category AS cat
ON cat.id = categoriesWithBrand.category_id
答案 2 :(得分:0)
您可以尝试CTE。
;with CategoryBrand as
(
select distinct c.id as category_id, brand
from category c
inner join device d on c.id = d.category_id
)
select c.*, d.*
from CategoryBrand cb
inner join Category c on c.id = cb.category_id
and cb.Brand = 'foo'
inner join Device d on c.id = d.category_id
CTE CategoryBrand建立了类别到品牌的映射。
下面的SQL仅获得类别,这些类别映射到所需的品牌,然后从该类别连接到设备。