Postgres很多到很多映射sql查询

时间:2014-05-28 22:22:07

标签: sql postgresql relational-division

Postgresql数据库

Table User
-----------
ID | Name

1  | John
2  | Bob
3  | Sarah


Table Photo
-------------
ID | Caption

1   | Vacation
2   | Birthday
3   | Christmas

Table Comment
--------------
ID | User ID | Photo ID| Text

1  |    1    |    1    | Mexico Looks Great
2  |    2    |    1    | Sure Does
3  |    3    |    1    | Too Hot
4  |    1    |    2    | Look at that cake
5  |    3    |    2    | No ice cream?
6  |    1    |    3    | So Happy

欲望:我想获得只有John(1)和Sara(3)评论过的所有照片。

如何构建一个SQL查询,查找只有来自用户#1和用户#3的评论的照片,我想要排除比那两个评论更多(或更少)的结果。

4 个答案:

答案 0 :(得分:1)

让我们做三个连接,一个用于约翰,一个用于sara,一个用于其他人。然后我们将使用where子句限制我们得到的内容。

select p.*
from photo p
left join comment john on john.photo_id=p.photo_id and john.user_id=1
left join comment sara on sara.photo_id=p.photo_id and sara.user_id=3
left join comment everyone_else on everyone_else.photo_id=p.photo_id and everyone_else.user_id<>3 and everyone_else.user_id<>1
where 
everyone_else.id is null
and john.id is not null
and sara.id is not null

答案 1 :(得分:1)

最清晰,最易读的方式是Photo包含评论:

User1 Intersect User2 Except任何其他用户

SQL Fiddle和查询将返回:

SELECT *
FROM Photo
WHERE ID IN (
    SELECT "Photo ID" FROM Comment WHERE "User ID" = 1
    INTERSECT
    SELECT "Photo ID" FROM Comment WHERE "User ID" = 3
    EXCEPT
    SELECT "Photo ID" FROM Comment WHERE "User ID" NOT IN (1, 3)
)

答案 2 :(得分:0)

有几种方法可以做到这一点。一种方法是将countcase

一起使用
select photoid
from comment
group by photoid
having count(distinct userid) = 2
  and count(case when userid not in (1,3) then 1 end) = 0

基本上,请确保2位用户已发表评论,然后确保只有用户1或3发表评论。

答案 3 :(得分:-1)

您可以使用十字路口仅查找常见照片,这些照片会排除约翰评论而不是莎拉评论的照片,反之亦然

select photo_id from comment where user_id = 1
intersect
select photo_id from comment where user_id = 3