找到看过相同节目的观众(每个节目匹配多行)

时间:2015-05-01 13:23:15

标签: sql postgresql aggregate-functions common-table-expression relational-division

对于作业,我必须为运行PostgreSQL 9.3.0的PostgreSQL服务器中存储的数据库编写几个SQL查询。但是,我发现自己被上次查询阻止了。数据库为歌剧院的预订系统建模。该查询是关于将观众与每次协助相同事件的其他观众相关联。

该模型如下所示:

Reservations table 
id_res |     create_date     |  tickets_presented  | id_show | id_spectator | price | category 
-------+---------------------+---------------------+---------+--------------+-------+----------
     1 | 2015-08-05 17:45:03 |                     |       1 |            1 |   195 |        1
     2 | 2014-03-15 14:51:08 | 2014-11-30 14:17:00 |      11 |            1 |   150 |        2

Spectators table

id_spectator   | last_name  | first_name |                email                   |     create_time     | age 
---------------+------------+------------+----------------------------------------+---------------------+-----   
             1 | gonzalez   | colin      | colin.gonzalez@gmail.com               | 2014-03-15 14:21:30 |  22
             2 | bequet     | camille    | bequet.camille@gmail.com               | 2014-12-10 15:22:31 |  22

Shows table
 id_show |          name          |  kind  | presentation_date | start_time | end_time | id_season | capacity_cat1 | capacity_cat2 | capacity_cat3 | price_cat1 | price_cat2 | price_cat3 
---------+------------------------+--------+-------------------+------------+----------+-----------+---------------+---------------+---------------+------------+------------+------------
       1 | madama butterfly       | opera  | 2015-09-05        | 19:30:00   | 21:30:00 |         2 |           315 |           630 |           945 |        195 |        150 |        100
       2 | don giovanni           | opera  | 2015-09-12        | 19:30:00   | 21:45:00 |         2 |           315 |           630 |           945 |        195 |        150 |        100

到目前为止,我已经开始编写一个查询来获取观众的身份和他正在参加的节目的日期,查询看起来像这样。

SELECT Reservations.id_spectator, Shows.presentation_date
FROM Reservations
LEFT JOIN Shows ON Reservations.id_show = Shows.id_show;

有人可以帮助我更好地理解问题并暗示我找到解决方案。提前谢谢。

所以我期待的结果应该是这样的

id_spectator | other_id_spectators
-------------+--------------------
            1|                 2,3

这意味着每次有身份1的观众去看演出时,观众2和3也会这样做。

3 个答案:

答案 0 :(得分:3)

基于评论的说明:希望明确这个答案可能用途有限,因为它在SQL-Server的上下文中得到了回答(标签当时存在)

可能有更好的方法,但你可以使用'stuff'功能。这里唯一的缺点是,因为你的id是整数,所以在值之间放置一个逗号将涉及一个解决方法(需要是一个字符串)。以下是我可以考虑使用解决方法的方法。

SELECT [id_spectator], [id_show]
, STUFF((SELECT ',' + CAST(A.[id_spectator] as NVARCHAR(10))
FROM reservations A
Where A.[id_show]=B.[id_show] AND a.[id_spectator] != b.[id_spectator] FOR XML PATH('')),1,1,'') As [other_id_spectators]
From reservations B
Group By [id_spectator], [id_show]

这将向您展示参加同一节目的所有其他观众。

答案 1 :(得分:0)

听起来你有一半的问题 - 确定哪个id_shows特定的id_spectator参加了。

您想要问自己的是如何在给定id_show的情况下确定哪些id_spectators参与了id_show。完成后,将两个答案结合起来得到完整的结果。

答案 2 :(得分:0)

所以我得到的最终答案如下:

SELECT id_spectator, id_show,(
    SELECT string_agg(to_char(A.id_spectator, '999'), ',')
    FROM Reservations A
    WHERE A.id_show=B.id_show
) AS other_id_spectators
FROM Reservations B
GROUP By id_spectator, id_show
ORDER BY id_spectator ASC;

打印出类似这样的内容:

id_spectator | id_show | other_id_spectators 
-------------+---------+---------------------
           1 |       1 |    1,   2,   9
           1 |      14 |    1,   2

哪个适合我的需求,但如果您有任何改进,请分享:)再次感谢大家!