在postgresql中复杂的视图语句

时间:2017-04-11 20:48:37

标签: postgresql join view

这是我的看法,我正在尝试输出名为'flightid','cancelledseats'和'reservedseats'的3列。但是当我执行它时,它会执行太多数据。我只想要一行而不是15行。

CREATE VIEW check_flight_status AS
SELECT
    (SELECT flightid FROM FLIGHTBOOKING WHERE flightid=111),
    (SELECT COUNT(flightID) FROM FLIGHTBOOKING
    WHERE status='c' AND flightid=111) AS cancelledseats, 
    (SELECT COUNT(flightid) FROM FLIGHTBOOKING 
    WHERE status='r' AND flightid=111) AS reservedseats
FROM flightbooking
INNER JOIN flight
ON flightbooking.flightid=flight.flightid;

(我无法在没有截屏的情况下向我展示我的桌子,因为在布局混乱的情况下,你无法在格式化文本中理解它。但是,我确实试过了)

Flight table

Flightbooking table

预期输出有3列(flightid,cancelledseats和reservedseats)和一行数据111,1,0。

修改

我刚刚解决了我的问题!

CREATE VIEW check_flight_status AS
SELECT
    (SELECT flightid FROM FLIGHTBOOKING WHERE flightid=111),
    (SELECT COUNT(flightID) FROM FLIGHTBOOKING
    WHERE status='c' AND flightid=111) AS cancelledseats, 
    (SELECT COUNT(flightid) FROM FLIGHTBOOKING 
    WHERE status='r' AND flightid=111) AS reservedseats
FROM flightbooking
INNER JOIN flight
ON flightbooking.flightid=flight.flightid
WHERE flight.flightid=111;

添加WHERE flight.flightid = 111;到最后,它只输出一行。但是,你相信我的观点过于复杂吗?可以更简单吗?

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的,查询包含不必要的复杂性元素,如果没有关于模式的更多信息,很难确定问题是什么以及您在此需要什么。但是,我建议,作为第一次尝试,您的额外行问题可能是您实际上没有使用WHERE子句过滤整个查询中的结果,尽管您在子查询中得到了过滤。

尝试以下方法:

CREATE VIEW check_flight_status AS
SELECT
    flightid,
    COUNT(*) FILTER (WHERE status = 'c') AS cancelledseats,
    COUNT(*) FILTER (WHERE status = 'r') AS reservedseats
FROM
    flight
    INNER JOIN flightbooking USING (flightid)
WHERE
    flightid = 111;

请注意:

  1. COUNT(*)在这里很好。我假设flightid是主键,不能为NULL。
  2. 方便的USING语法,简化了使用具有相同名称的字段的连接。
  3. 在select子句中使用过滤器,这是在没有子查询的情况下获取所需数据的众多方法之一。
  4. COUNT聚合应将行数减少为1,而WHERE子句将限制计数对特定航班的影响。
  5. 同样,如果没有关于相关表格的架构或信息,很难确定您需要的查询,并且如果没有更好地描述您的问题,很难确定您想要的输出。

    通常,如果您只需要一行中的一行,则可以在查询中添加LIMIT 1,但如果没有正确结构化的查询和特定意图,则不应该这样做,我认为这不是LIMIT 1合适的情况。