SQL根据第二个表中的值列表从第一个表中选择

时间:2013-10-21 05:05:32

标签: sql postgresql

我有这样的表“人”

  id  |  firstName  |  lastName  |  ...
-----------------------------------------
  1   | Bill        | Gates      |
  2   | Steve       | Jobs       |
  3   | Linus       | Torvalds   |

和第二个表“美德”就像这样

  id  | person_id | v_key    | v_value
---------------------------------------------
  1   | 1         | OS       | Windows Mobile
  2   | 1         | Company  | Microsoft
  3   | 2         | OS       | iOS
  4   | 2         | Company  | Apple

我可以为所有这样的人计算美德

select a.firstName, a.lastName, count(b.v_key)
  from person a
  left join virtue b on b.person_id = a.id
  group by a.firstName, a.lastName

现在我需要从第一张桌子中选择所有给出“OS”=“iOS”,“公司”=“Apple”等美德列表的人。

2 个答案:

答案 0 :(得分:1)

如果你需要获取拥有所有美德的人,那么你可以使用group by并过滤count

with cte_given_list as (
    select *
    from (values ('OS', 'iOS'), ('Company', 'Apple')) as c(v_key, v_value)
)
select
    p.firstName, p.lastName
from cte_given_list as c
    inner join virtue as v on v.v_key = c.v_key and v.v_value = c.v_value
    inner join person as p on p.id = v.person_id
group by p.id
having count(*) = (select count(*) from cte_given_list as t)

请注意,我在这里按ID进行分组,但选择名称。如果id是person表中的主键,那么在PostgreSQL中是可能的。

<强> sql fiddle demo

答案 1 :(得分:0)

如果我读得正确,唯一的额外标准是操作系统= IOS和公司= Apple,您对其他选项不感兴趣。在这种情况下,你可以使用这样的东西:

  

选择a.firstName,a.lastName   来自人a   在b.person_id = a.id上左加入美德b   AND(b.v_key ='OS'和b.v_value ='iOS')或(b.v_key ='Company'AND b.v_value ='Apple')   group by a.firstName,a.lastName

如果您需要通过操作系统或公司逐个提取操作系统,您可以考虑将它们作为参数提供。

这就是你要找的东西吗?