PostgreSQL查询中length_of_stay列值全为第一行值的问题
问题分析:PostgreSQL查询中length_of_stay列值全部重复
原查询代码
select price_total, check_in_date, check_out_date, price_total / length_of_stay as price_per_day, length_of_stay from (select check_out_date - check_in_date as length_of_stay from bookings b)as table1, bookings b2;
查询输出
| price_total | check_in_date | check_out_date | price_per_day | length_of_stay |
|---|---|---|---|---|
| 1428.30 | 2018-08-30 | 2018-09-03 | 357.0750000000000000 | 4 |
| 269.37 | 2020-02-11 | 2020-02-14 | 67.3425000000000000 | 4 |
| 111.93 | 2020-12-28 | 2020-12-29 | 27.9825000000000000 | 4 |
| 1131.13 | 2020-02-26 | 2020-02-29 | 282.7825000000000000 | 4 |
| 391.80 | 2020-06-11 | 2020-06-12 | 97.9500000000000000 | 4 |
| 336.00 | 2020-06-11 | 2020-06-12 | 84.0000000000000000 | 4 |
| 293.82 | 2020-02-16 | 2020-02-18 | 73.4550000000000000 | 4 |
| 2236.92 | 2018-09-24 | 2018-09-27 | 559.2300000000000000 | 4 |
原因分析
你的查询存在两个核心问题:
- 无关联的笛卡尔积:用逗号连接子查询
table1和主表b2但未指定连接条件,触发了笛卡尔积逻辑——table1的每一行都会和b2的每一行强制匹配。 - 子查询未关联主表:子查询
table1独立计算了整个bookings表的所有停留时长,但没有通过主键(比如booking_id)和b2做关联匹配,导致PostgreSQL默认将table1的第一行值重复映射到b2的所有行上,最终所有结果的length_of_stay都显示为第一行的4。
修正后的查询方案
方案1:直接计算(最简单高效)
不需要子查询,直接在主查询中计算每条记录的停留时长:
select price_total, check_in_date, check_out_date, price_total / (check_out_date - check_in_date) as price_per_day, check_out_date - check_in_date as length_of_stay from bookings;
方案2:带关联的子查询(适用于复杂场景)
如果必须用子查询,需通过主键将子查询与主表关联:
select b2.price_total, b2.check_in_date, b2.check_out_date, b2.price_total / table1.length_of_stay as price_per_day, table1.length_of_stay from (select booking_id, check_out_date - check_in_date as length_of_stay from bookings)as table1 join bookings b2 on table1.booking_id = b2.booking_id;
内容的提问来源于stack exchange,提问作者vikwillberg
相关产品推荐
相关产品推荐

