【问题标题】:PostgreSQL get aggregated results based on two tablesPostgreSQL 基于两张表获取聚合结果
【发布时间】:2017-11-09 17:32:19
【问题描述】:

我有两张桌子,
1.items
2.festival_rents

样本记录: items

id | name   |  rent 
------------------------
1  |  Car   |   100             
2  |  Truck |   150   
3  |  Van   |   200   

样本记录: festival_rents

id | items_id   | start_date | end_date   | rent 
------------------------------------------------
1  |  1         | 2018-07-01 | 2018-07-02 | 200  
2  |  1         | 2018-07-04 | 2018-07-06 | 300
3  |  3         | 2018-07-06 | 2018-07-07 | 400

items 包含namerent 的项目列表。 items 表中的每个项目可能有也可能没有festival_rents。在start_dateend_date 的日期范围内,festival_rents 表的每个项目的租金都较高。一个项目可能有多个具有不同日期范围的festival_rents。但可以肯定的是,属于同一 item 的多个 festival_rents 的日期范围不会发生冲突,并且所有日期范围都是孤立的。

我要查找的查询是,对于给定的start_dateend_date 范围,对于items 表中的每个项目,计算总租金并显示每个项目及其计算的总租金。如果items 中的任何一个festival_rents 属于给定的start_dateend_date,则每个项目的租金计算也应包括festival_rents

预期结果:

输入:start_date=2018-07-01end_date=2018-07-06

输出:

id | name   | total_price 
------------------------
1  |  Car   |   1100          // 1st 2 days festival rent + 1 day normal rent + last 3 days festival rent (2 * 200) + (1 * 100) + (3 * 200)  
2  |  Truck |   900           // 6 days normal rent (6 * 150)
3  |  Van   |   1400          // 5 days normal rent + 1 day festival rent (200 * 5) + (400 * 1)   

【问题讨论】:

  • mysql 还是 postgresql?选择一个。
  • 是的,PostgreSQL。

标签: postgresql


【解决方案1】:

您需要在表格上或即时创建的日期列表:

How to get list of dates between two dates in mysql select query

Generating time series between two dates in PostgreSQL

SELECT i.name, SUM (f.rent)
FROM allDays a
JOIN festival_rents f
  ON a.day >= f.start_date 
 AND a.day < f.end_date  
JOIN items i
  ON f.item_id = i.item_id 
WHERE a.day BETWEEN @start_date
                AND @end_date
GROUP BY i.name

我假设 end_date 是开放范围。所以如果你有[A,B)[B,C)范围,日期B的租金来自[B,C)

【讨论】:

  • 是否可以在不动态创建表的情况下进行聚合?我不明白你的意思是end_date 在你答案的最后一行是开放范围。如果您在谈论festival_rents 中的end_date,则 end_dates 不会与其他festival_rents 范围冲突。因此,对于您给出的示例,它将是 [A, A][B, C]
  • 开放范围意味着:start &lt;= value &lt; end .... 近距离意味着:start &lt;= value &lt;= end。这是不可能的,因为您需要为每一天分配一个属性。您可以创建一个永久表来保存所有日期。每年只有365 行。或36.500 100 年所以没什么大不了的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-02-23
  • 2016-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多