【发布时间】:2012-03-25 11:35:18
【问题描述】:
给定以下表格:
shows:
title | basic_ticket_price
----------------+--------------------
Inception | $3.50
Romeo & Juliet | $2.00
performance:
perf_date | perf_time | title
------------+-----------+----------------
2012-08-14 | 00:08:00 | Inception
2012-08-12 | 00:12:00 | Romeo & Juliet
booking:
ticket_no | perf_date | perf_time | row_no | person_id
-----------+------------+-----------+--------+-----------
1 | 2012-08-14 | 00:08:00 | P01 | 1
2 | 2012-08-12 | 00:12:00 | O05 | 4
3 | 2012-08-12 | 00:12:00 | A01 | 2
还有一个额外的表格:seat,其中包含一个座位列表,编号与预订中的 row_no 相同,带有区域名称。
使用此语句对预订的座位进行分组:
select count(row_no) AS row_no,
area_name
from seat
where exists (select row_no
from booking
where booking.row_no = seat.row_no)
group by area_name;
产生:
row_no | area_name
--------+--------------
1 | rear stalls
2 | front stalls
我现在如何使用计数的行数和 area_name 编写一条 SQL 语句来生成一个列表,显示节目名称、演出日期和时间以及每个区域的预订座位数?
我试过了:
select s.title,
perf_date,
perf_time,
count(row_no) AS row_no,
area_name
from shows s,
performance,
seat
where exists (select row_no
from booking
where booking.row_no = seat.row_no)
group by area_name,s.title,performance.perf_date,performance.perf_time;
但它显示重复的行:
title | perf_date | perf_time | row_no | area_name
----------------+------------+-----------+--------+--------------
Romeo & Juliet | 2012-08-12 | 00:12:00 | 1 | rear stalls
Romeo & Juliet | 2012-08-14 | 00:08:00 | 2 | front stalls
Inception | 2012-08-12 | 00:12:00 | 1 | rear stalls
Inception | 2012-08-14 | 00:08:00 | 2 | front stalls
Inception | 2012-08-14 | 00:08:00 | 1 | rear stalls
Inception | 2012-08-12 | 00:12:00 | 2 | front stalls
Romeo & Juliet | 2012-08-14 | 00:08:00 | 1 | rear stalls
Romeo & Juliet | 2012-08-12 | 00:12:00 | 2 | front stalls
(8 rows)
任何解决此问题的帮助将不胜感激。
【问题讨论】:
-
另外:您在第二个语句中缺少连接条件。它将在表演、表演和座位之间产生一个笛卡尔连接。你最好用
JOIN ...重写它 -
请接受我的歉意,我正在使用 psql 但也将其标记为 mysql,因为我发现大多数语句与 select 语句相似。
-
您应该使用序列号作为主键。如果你有第二个放映电影的房间怎么办?你不能让两部电影同时发生,因为它们是由 perf_date 和 perf_time 标识的。或者在安排演出时该怎么办?您必须修改多个表,这是一件坏事。还有一个小建议:我不会在列名中重复表标题。否则以 perf.perf_title 结尾 - perf.title 就足够了。
-
@userunknown:
perf_date实际上是一个可接受的标识符选择。您不想滥用类型名称作为列名。除此之外,它真的应该是timestamp。我会添加一个答案。
标签: sql postgresql