自连接删除了几个表
Self Join Several Tables Removed
我有 4 个 table:resources
、feature_resources
、features
和 feature_types
。
一个resource
有很多features
(使用feature_resources
作为连接table),每个feature
有一个feature_type
。
我需要检查一个特定的 resource
是否同时具有 features
和 RESOURCE_TYPE
和 LIBRARY
。
我尝试了以下方法,但没有用:
SELECT * FROM resources
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS f1 ON f1.id = feature_resources.feature_id
INNER JOIN features AS f2 ON f2.id = feature_resources.feature_id
INNER JOIN feature_types AS ft1 ON ft1.id = f1.feature_type_id
INNER JOIN feature_types AS ft2 ON ft2.id = f2.feature_type_id
WHERE ft1.value = 'RESOURCE_TYPE'
AND ft2.value = 'LIBRARY'
我认为问题在于 feature.id
会有所不同,只有 resource.id
会相同。我用 LEFT JOIN
尝试了上面的代码,但它仍然不起作用。
我目前的解决方案是子查询方法:
SELECT "resources".*
FROM "resources"
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS featureTwo ON featureTwo.id = feature_resources.feature_id
INNER JOIN feature_types AS featureTypeTwo ON featureTwo.feature_type_id = featureTypeTwo.id
WHERE "resources"."id"
IN
(SELECT "resources"."id"
FROM "resources"
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS featureOne ON feature_resources.feature_id = featureOne.id
INNER JOIN feature_types AS featureTypeOne ON featureOne.feature_type_id =
featureTypeOne.id
WHERE (featureOne.string_value = 'ZONE')
AND (featureTypeOne.value = 'RESOURCE_TYPE'))
AND (featureTypeTwo.value = 'LIBRARY')
这行得通,只是好奇是否有办法使用内部联接而不是子查询。
我正在使用 postgres,但任何通用的 SQL 答案都会很有趣。
数据
资源:
| id | description |
| 1 | Office |
feature_resources:
| resource_id | feature_id |
| 1 | 1 |
| 1 | 2 |
特点:
| id | string_value | feature_type_id |
| 1 | Zone | 1 |
| 2 | nil | 2 |
feature_types:
| id | value |
| 1 | RESOURCE_TYPE |
| 2 | LIBRARY |
一种方法是使用聚合来确定您需要哪些资源:
类似于:
select resources.id, resources.description
from
resources
join
feature_resources
on
resources.id = feature_resources.resource_id
join
features
on
feature_resources.features_id = features.id
join
feature_types
on
features.feature_type_id = feature_types.id
where
feature_types.value in ( 'RESOURCE_TYPE', 'LIBRARY' )
group by
resources.id, resources.description
having
count(*) = 2
试试这个
select
r.*
from
feature_resources fr
inner join resources r on
r.id = fr.resource_id
inner join features f on
f.id = fr.feature_id
inner join feature_types ft on
ft.id = f.feature_type_id
where
ft.value in ('resource_type', 'library')
group by
r.id
having
count(*) = 2;
我有 4 个 table:resources
、feature_resources
、features
和 feature_types
。
一个resource
有很多features
(使用feature_resources
作为连接table),每个feature
有一个feature_type
。
我需要检查一个特定的 resource
是否同时具有 features
和 RESOURCE_TYPE
和 LIBRARY
。
我尝试了以下方法,但没有用:
SELECT * FROM resources
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS f1 ON f1.id = feature_resources.feature_id
INNER JOIN features AS f2 ON f2.id = feature_resources.feature_id
INNER JOIN feature_types AS ft1 ON ft1.id = f1.feature_type_id
INNER JOIN feature_types AS ft2 ON ft2.id = f2.feature_type_id
WHERE ft1.value = 'RESOURCE_TYPE'
AND ft2.value = 'LIBRARY'
我认为问题在于 feature.id
会有所不同,只有 resource.id
会相同。我用 LEFT JOIN
尝试了上面的代码,但它仍然不起作用。
我目前的解决方案是子查询方法:
SELECT "resources".*
FROM "resources"
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS featureTwo ON featureTwo.id = feature_resources.feature_id
INNER JOIN feature_types AS featureTypeTwo ON featureTwo.feature_type_id = featureTypeTwo.id
WHERE "resources"."id"
IN
(SELECT "resources"."id"
FROM "resources"
INNER JOIN feature_resources ON feature_resources.resource_id = resources.id
INNER JOIN features AS featureOne ON feature_resources.feature_id = featureOne.id
INNER JOIN feature_types AS featureTypeOne ON featureOne.feature_type_id =
featureTypeOne.id
WHERE (featureOne.string_value = 'ZONE')
AND (featureTypeOne.value = 'RESOURCE_TYPE'))
AND (featureTypeTwo.value = 'LIBRARY')
这行得通,只是好奇是否有办法使用内部联接而不是子查询。
我正在使用 postgres,但任何通用的 SQL 答案都会很有趣。
数据
资源:
| id | description |
| 1 | Office |
feature_resources:
| resource_id | feature_id |
| 1 | 1 |
| 1 | 2 |
特点:
| id | string_value | feature_type_id |
| 1 | Zone | 1 |
| 2 | nil | 2 |
feature_types:
| id | value |
| 1 | RESOURCE_TYPE |
| 2 | LIBRARY |
一种方法是使用聚合来确定您需要哪些资源: 类似于:
select resources.id, resources.description
from
resources
join
feature_resources
on
resources.id = feature_resources.resource_id
join
features
on
feature_resources.features_id = features.id
join
feature_types
on
features.feature_type_id = feature_types.id
where
feature_types.value in ( 'RESOURCE_TYPE', 'LIBRARY' )
group by
resources.id, resources.description
having
count(*) = 2
试试这个
select
r.*
from
feature_resources fr
inner join resources r on
r.id = fr.resource_id
inner join features f on
f.id = fr.feature_id
inner join feature_types ft on
ft.id = f.feature_type_id
where
ft.value in ('resource_type', 'library')
group by
r.id
having
count(*) = 2;