自我加入删除了几个表

时间:2015-04-23 15:23:46

标签: sql postgresql join subquery

我有4个表:resourcesfeature_resourcesfeaturesfeature_types

resource有很多features(使用feature_resources作为联接表),每个feature都有feature_type

我需要检查特定的resource是否features同时包含RESOURCE_TYPELIBRARY

我尝试了以下操作,但它不起作用:

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       |

2 个答案:

答案 0 :(得分:0)

一种方法是使用聚合来确定您需要哪些资源: 类似的东西:

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

答案 1 :(得分:0)

试试这个

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;