2016-07-26 25 views
0

我有以下关系:如何在PotgreSQL中选择所有关联记录ID的数组?

Place(1) |----< (N)SavedPlace(N) >----| (1)Visitor 

所以:

  • 一个Place能够被许多Visitors
  • 一个SavedPlace保存节省整整Place
  • 一个SavedPlace是由一个人完全保存Visitor
  • One Visitor可以节省很多Places

我想:

  • 指望有多少次一个Place保存在一般 - 我想这与SavedPlaces加盟Places,通过Place ID将它们分组和计数多少SavedPlaces ID是每个组
  • 看看Visitor保存了Place - 我想这是每个地方有一个Visitors ID列表。

第一个我做的事:

from place in query, 
    left_join: saved_places in assoc(place, :saved_places), 
    group_by: place.id, 
    select: %{place | saved_count: count(saved_places.id)} 

对于第二个,我不知道。

SQL应该如何查询这两个值?


编辑:

我意识到,我没有正确地描述第二个用例。我想查询所有Places,并为他们每个人分辨是否由特定的Visitor(知道他的身份证号)保存。

+2

你有问题吗? – aquinas

+1

你尝试了什么? –

+0

你想写的查询得到1)每个地方和它已经保存了多少次2)访问过一个特定地点的访问者列表? –

回答

1

你找两个查询:

计数一个地方是多少次救一般 - 我想这是加入与SavedPlaces地方,由地方ID将它们分组和计数多少SavedPlaces ID为每每组

select  places.place_id, places.place_name, Count(*) 
from  places 
inner join savedplaces on savedplaces.place_id = places.place_id 
group by places.place_id, places.place_name 

如果有可能的访问者留有一个地方的两倍(这是否感觉在你的应用程序?),要一次算这样的重复,然后用Count(distinct savedplaces.visitor_id)代替Count(*)

对于其他要求:

看到如果访问者保存一个地方 - 我想这为具有每一个地方游客ID列表。

select  places.place_id, places.place_name, visitors.visitor_id, visitors.visitor_name 
from  places 
inner join savedplaces on savedplaces.place_id = places.place_id 
inner join visitors on visitors.visitor_id = savedplaces.visitor_id 

要知道保存在特定地点的游客,加where条款:

where  places.place_id = ? 

...其中?代表你想获得游客的任何place_id。

同样,要知道一个特定访问者储存的位置,使用where条款:

where  places.visitor_id = ? 

...其中?代表你想要得到保存的地方无论visitor_id。

如果要列出所有的地方,和特定访问者是否已经救了它的指示(是/否),那么你可以使用外(left)加入:

select  places.place_id, places.place_name, 
      case when savedplaces.visitor_id is null then 'No' else 'Yes' end 
from  places 
left join savedplaces on savedplaces.place_id = places.place_id 
     on savedplaces.visitor_id = ? 

同样,如果要列出所有访问者,以及他们是否保存在特定地点的指示(是/否),那么你可以使用外(left)加入,以及:

select  visitors.visitor_id, visitors.visitor_name, 
      case when savedplaces.place_id is null then 'No' else 'Yes' end 
from  visitors 
left join savedplaces on savedplaces.visitor_id = visitors.visitor_id 
     on savedplaces.place_id = ? 
+0

如果我想知道他们是否被特定访客保存过的所有地方,该怎么办? – squixy

+0

为我的答案增加了两个查询,其中一个查询会回答。 – trincot

1

您可以编写查询如下所示

1)

SELECT p1.name, x.placeCount 
FROM Place p1 INNER JOIN 
(SELECT p2.id, COUNT(s.placeId) as placeCount 
FROM Place p2 
INNER JOIN SavedPlace s 
ON p2.id = s.placeId 
GROUP BY p2.id) x 
ON p1.id = x.id 

2)

SELECT v.name 
FROM SavedPlace s 
INNER JOIN Visitor v 
ON s.vistorId = v.id 
WHERE s.placeId = <your_place_id>