【发布时间】:2022-01-03 22:43:26
【问题描述】:
我已经问过这个问题here,但关于我的问题的信息较少。因此,我创建了一个包含更多信息的新问题。
这是我的示例表。每行包含用户每次填写的数据。这样 timestamp 列将不会在整个表中为 null。如果用户没有填写,item下可能有未记录的值。 id 是为每条记录自动生成的列。
CREATE TABLE tbl (id int, customer_id text, item text, value text, timestamp timestamp);
INSERT INTO tbl VALUES
(1, '001', 'price', '1000', '2021-11-01 01:00:00'),
(2, '001', 'price', '1500', '2021-11-02 01:00:00'),
(3, '001', 'price', '1400', '2021-11-03 01:00:00'),
(4, '001', 'condition', 'good', '2021-11-01 01:00:00'),
(5, '001', 'condition', 'good', '2021-11-02 01:00:00'),
(6, '001', 'condition', 'ok', '2021-11-03 01:00:00'),
(7, '001', 'feeling', 'sad', '2021-11-01 01:00:00'),
(8, '001', 'feeling', 'angry', '2021-11-02 01:00:00'),
(9, '001', 'feeling', 'fine', '2021-11-03 01:00:00'),
(10, '002', 'price', '1200', '2021-11-01 01:00:00'),
(11, '002', 'price', '1600', '2021-11-02 01:00:00'),
(12, '002', 'price', '2000', '2021-11-03 01:00:00'),
(13, '002', 'weather', 'sunny', '2021-11-01 01:00:00'),
(14, '002', 'weather', 'rain', '2021-11-02 01:00:00'),
(15, '002', 'price', '1900', '2021-11-04 01:00:00'),
(16, '002', 'feeling', 'sad', '2021-11-01 01:00:00'),
(17, '002', 'feeling', 'angry', '2021-11-02 01:00:00'),
(18, '002', 'feeling', 'fine', '2021-11-03 01:00:00'),
(19, '003', 'price', '1000', '2021-11-01 01:00:00'),
(20, '003', 'price', '1500', '2021-11-02 01:00:00'),
(21, '003', 'price', '2000', '2021-11-03 01:00:00'),
(22, '003', 'condition', 'ok', '2021-11-01 01:00:00'),
(23, '003', 'weather', 'rain', '2021-11-02 01:00:00'),
(24, '003', 'condition', 'bad', '2021-11-03 01:00:00'),
(25, '003', 'feeling', 'fine', '2021-11-01 01:00:00'),
(26, '003', 'weather', 'sunny', '2021-11-03 01:00:00'),
(27, '003', 'feeling', 'sad', '2021-11-03 01:00:00')
;
为了看得清楚,我按照id和timestamp对上表进行排序。没关系。
- 我们使用的是 Postgresql 版本:PostgreSQL 9.5.19
- 实际表包含超过 400 万行
- item 列包含 500 多个不同的项目,但不要担心。我将最多使用 10 个项目进行查询。在上表中,我只使用了 4 个项目。
- 我们还有另一个名为 Customer_table 的表,其中包含包含客户一般信息的唯一 Customer_id。
从上表中,我想查询数据以创建一个包含最新日期更新数据的表,如下所示。我将最多使用 10 个项目进行查询,因此可能有 10 列。
customer_id price condition feeling weather .......(there may be other columns from item column)
002 1900 null fine rain
001 1400 ok fine null
003 2000 bad sad sunny
这是我从previous questions 得到的查询,但我只询问了两个item。
SELECT customer_id, p.value AS price, c.value AS condition
FROM (
SELECT DISTINCT ON (customer_id)
customer_id, value
FROM tbl
WHERE item = 'condition'
ORDER BY customer_id, timestamp DESC
) c
FULL JOIN (
SELECT DISTINCT ON (customer_id)
customer_id, value
FROM tbl
WHERE item = 'price'
ORDER BY customer_id, timestamp DESC
) p USING (customer_id)
所以,如果有更好的解决方案,请帮助我。 谢谢。
【问题讨论】:
-
表定义的规范形式是
CREATE TABLE语句包括所有约束。显示PK、NOT NULL等,并公开相关索引!没有多少散文可以弥补这一点。此外,Postgres 9.5 已于 2021 年 2 月 EOL。升级到当前版本!大表有重大改进。甚至还有可能适用于您的情况的新功能,例如WITH TIES。 -
也很重要:每个客户的粗略行数(最小/最大/平均)——当然是相关项目,因为其余的可以很便宜地排除在外。以及不同客户的数量:
SELECT count(*) FROM Customer_table;并且:您是否一次查询所有客户以进行选择?如果有,具体是什么选择? -
customer_table中还有一些更多信息,例如 customer_type 或 location 等。所以,我们通过过滤查询客户表单customer_table,并连接两个表(customer_table和我要求查询的表)形成所需的表。 -
we query the customer form customer_table by filtering客户?你是说一个客户?如果每个查询是一个或几个或多个或所有客户,这一切都会有所不同。 -
对不起,我的错误。我们通过过滤 customer_type 或 location 等查询来自
customer_table的客户,以对该用户进行分析。然后我们通过 item 列下的 item names 从上面的巨大表中查询我们要分析的列。然后我们根据需要加入或做其他操作。
标签: sql postgresql greatest-n-per-group