在PostgreSQL中,表Sales
包含以下数据:
| id(PK) | eva_dts_id(FK) | realm_name | device_id | timestamp | product_id | product_name | quantity | product_price | revenue |
realm_name
和device_id
是常量,即使它们在将来发生变化,它们也会在此表中相应地更新。
我尝试使用以下模式在其上创建视图Products
:
| realm_name | device_id | product_id | product_name | product_price |
到目前为止,我使用了以下查询:
SELECT DISTINCT realm_name, device_id, product_id, product_name, product_price
FROM public.Sales;
假设设备的产品列表是不可变的,所以将来不会改变。我想释放这个假设,并为设备创建一个产品列表数据,始终考虑最近的记录(基于Sales
表中找到的timestamp
)。例如,如果我有一个产品“Chocomilk”,它有记录:
| id(PK) | eva_dts_id(FK) | realm_name | device_id | timestamp | product_id | product_name | quantity | product_price | revenue |
"03ef91f6-bb24-4c8e-90ef-366cc4dee5a6" "e853dcec-c369-4111-816d-1645067df8e1" "tenant" "RbbMIyemWTOI99N6XZx1hA" "2023-03-26 22:43:31.454734" "10" "Chocomilk" 1 0.38 0
"03ef91f6-bb24-4c8e-90ef-366cc4dee5a6" "e853dcec-c369-4111-816d-1645067df8e1" "tenant" "RbbMIyemWTOI99N6XZx1hA" "2023-04-12 22:43:31.454734" "10" "Chocomilk" 1 2.3 0
"03ef91f6-bb24-4c8e-90ef-366cc4dee5a6" "e853dcec-c369-4111-816d-1645067df8e1" "tenant" "RbbMIyemWTOI99N6XZx1hA" "2023-05-18 22:43:31.454734" "10" "Chocomilk" 1 1.5 0
我只考虑最后一个记录。
如何重写视图查询以实现此目的?
5条答案
按热度按时间xoefb8l81#
使用
ROW_NUMBER()
按时间戳排序你的物品信息,只获取最新的。仔细检查
ROW_NUMBER()
的PARTITION BY
子句,以包含项目的唯一标识符,该标识符不会随时间而更改。ldfqzlk82#
对@markalex的答案提出了另一种解决方案,并遵循@tinazmu的建议:
hgb9j2n63#
Postgres提供了另一种选择:select语句的Distinct on子句。该子句的结果是保持在第一行匹配distinct on表达式(根据短语顺序)。您要查找的是:(参见demo)
注意:恕我直言,命名一个列
timestamp
是一个糟糕的做法,因为它是一个SQL保留字和一个Postgres数据类型(尽管不是Postgres保留的)。我在上面和演示中已经替换了sale_ts
。fgw7neuy4#
对于这样的查询,我更喜欢使用公共表表达式,它可以更容易地识别数据是什么以及如何过滤它。
Row_number和partition,给予查询引擎更好地了解你实际上在寻找什么。Sql是一种声明性语言,只要有可能,你就应该描述你想要的东西,而不是做一些技巧来引导它找到正确的答案。
krcsximq5#
另一个选项(可能更直观)是使用EXISTS函数过滤掉较旧的记录:
此查询将确保同一product_id没有任何更新的记录