【问题标题】:SQL natural join POSTGRESSQL 自然连接 POSTGRES
【发布时间】:2011-01-21 00:14:49
【问题描述】:

我不确定我需要什么样的连接,因为我不熟悉尝试以这种方式重叠数据,或者它是否可行。

我有两个表,它们共享一组相似的数据,并且都通过 Room_id. 与第三个父表相关

我有一个名为 Room_rates 的表,它存储每个房间的平均价格 (room_id)

+-------+---------+-----------+-------+--------+---------------------------+---------------------------+
| id    | room_id | dayofweek | price | source | created_at                | updated_at                |
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+
| 87936 | 2517    | 0         | 14.58 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87937 | 2517    | 1         | 14.58 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87938 | 2517    | 2         | 14.52 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87939 | 2517    | 3         | 14.52 | 1      | 2010-02-22 17:47:14 +0100 | 2010-02-22 17:47:14 +0100 |
| 87940 | 2517    | 4         | 14.52 | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
| 87941 | 2517    | 5         | 14.4  | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
| 87942 | 2517    | 6         | 14.63 | 1      | 2010-02-22 17:47:15 +0100 | 2010-02-22 17:47:15 +0100 |
+-------+---------+-----------+-------+--------+---------------------------+---------------------------+

还有一个名为“可用”的表格,其中包含特定日期的费率

+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+
| id     | price | spots | bookdate   | room_id | created_at                | updated_at                | source |
+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+
| 221389 | 14.3  | 1     | 2010-03-01 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221390 | 14.3  | 1     | 2010-03-02 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221391 | 14.3  | 1     | 2010-03-03 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-21 22:31:06 +0100 | 1      |
| 221392 | 14.3  | 1     | 2010-03-04 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 221393 |       | 0     | 2010-03-05 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 221394 |       | 0     | 2010-03-06 | 2517    | 2010-02-21 22:31:06 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228185 |       | 0     | 2010-03-07 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228186 | 14.3  | 1     | 2010-03-08 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228187 | 14.3  | 1     | 2010-03-09 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
| 228188 | 14.3  | 1     | 2010-03-10 | 2517    | 2010-02-22 17:47:19 +0100 | 2010-02-22 17:47:19 +0100 | 1      |
+--------+-------+-------+------------+---------+---------------------------+---------------------------+--------+

目前我正在使用两个单独的搜索结果,要么存在特定日期范围的当前Availables 数据,要么不存在。如果不是,我使用仅使用 Room_rate 平均值的备份查询。

我想在有可用价格的情​​况下使用 Availables,但如果价格不可用或可能根本没有记录,我想以某种方式加入 Room_rates 以填补空白。

我怎样才能做到这一点?

【问题讨论】:

    标签: sql postgresql join inner-join natural-join


    【解决方案1】:

    COALESCE 函数可以与连接结合使用,为您提供所需的内容:

    SELECT COALESCE(a.price, rr.price) 
      FROM Availables AS a
      FULL OUTER JOIN room_rates AS rr
        ON a.room_id = rr.room_id
      WHERE a.room_id=[id]
        AND a.bookdate=[date]
        AND rr.dayofweek=[dayofweek]
    

    您需要在适当的列上建立索引才能使其发挥作用。您还需要 compare the execution plan 反对替代方案(例如 Bruno 建议的 UNION),看看加入是否值得。

    【讨论】:

      【解决方案2】:

      连接不是这种情况。连接会将一个表中的数据与另一个表中的数据进行匹配。例如,为了匹配房间和 room_rates,您将使用连接。但是您不想匹配 Available 和 Room_rates。您想从 Available 中获取价格,或者 - 如果在 Avaiable 中找不到,则从 Room_rates 获取。

      因此,您确实必须首先在 Available 上运行查询,然后在需要时对 Room_rates 进行查询。

      您可以获得查询返回的第一个结果,类似于:

      select price from Availables where room_id=[id] and bookdate=[date]
      union
      select price from room_rates where room_id=[id] and dayofweek=[day of week]
      

      但我真的不建议这样做,因为即使不需要,也会运行第二个“选择”。所以最好只在需要时运行第一个选择,然后再运行第二个选择。

      【讨论】:

        猜你喜欢
        • 2013-04-13
        • 2011-06-17
        • 2015-02-09
        • 2020-02-16
        • 2019-03-09
        • 2013-02-26
        • 1970-01-01
        • 2010-10-18
        • 2014-07-07
        相关资源
        最近更新 更多