Bat*_*son 12 sql database postgresql null select
这是一个我一直绞尽脑汁的问题.假设我有一个表,其中包含一系列时间戳和一个部件号作为主键.该表存储增量更改,这意味着对于每个时间戳,如果字段更改,则记录该更改.如果该字段未更改,则对于新时间戳,它为NULL.这是基本的想法.
part | timestamp | x-pos | y-pos | status
------+-----------+-------+-------+--------
a5 | 151 | 5 | 15 | g
a5 | 153 | NULL | 17 | NULL
Run Code Online (Sandbox Code Playgroud)
(part, timestamp)是主键.NULL第二条记录中的s表示自第一条记录以来未改变的值.
我希望能够做的是为部件分组的每个字段选择最新值.例如,给定上述条目,对于a5部分,结果将为153,5,17,g.
截至目前,我已将此黑客一起查询.
((SELECT x-pos FROM part_changes WHERE x-pos IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1)
UNION
(SELECT y-pos FROM part_changesWHERE y-pos IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1)
UNION
(SELECT status FROM part_changes WHERE status IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1))
Run Code Online (Sandbox Code Playgroud)
但这会返回一个列,这意味着我可以使用group-by进行组织.
必须有更优雅的做事方式,例如以创造性的方式使用COALESCE或IS NULL.但是我被困住了,无法弄明白.有人有个主意吗?
不,我无法改变数据库结构.
编辑:鲁赫有正确的想法.现在唯一的问题是按部分分组.我似乎无法绕过LIMIT 1多个部分进行分组.有任何想法吗?
mdahlman,我对postgresql中的分析函数不太熟悉.因此,如果该解决方案比复杂查询更容易,那么通过各种方式发布您的想法.
编辑2:谢谢大家的帮助.我想我已经掌握了我需要做的事情.
而不是使用a UNION,听起来你真的想要字段列表中的子查询.也就是说,而不是(SELECT ...) UNION (SELECT ...) UNION (SELECT ...)你想要的SELECT (SELECT ...), (SELECT ...), (SELECT ...).
例如:
SELECT part,
( SELECT x_pos
FROM part_changes
WHERE part = pc.part
AND x_pos IS NOT NULL
ORDER
BY timestamp DESC
LIMIT 1
) AS x_pos,
( SELECT y_pos
FROM part_changes
WHERE part = pc.part
AND y_pos IS NOT NULL
ORDER
BY timestamp DESC
LIMIT 1
) AS y_pos,
( SELECT status
FROM part_changes
WHERE part = pc.part
AND status IS NOT NULL
ORDER
BY timestamp DESC
LIMIT 1
) AS status
FROM ( SELECT DISTINCT
part
FROM part_changes
) AS pc
;
Run Code Online (Sandbox Code Playgroud)
但在这一点上,我真的会考虑编写一个存储过程.
或者:
SELECT DISTINCT
part,
FIRST_VALUE(x_pos) OVER
( PARTITION BY part
ORDER BY CASE WHEN x_pos IS NULL
THEN NULL
ELSE TIMESTAMP
END DESC NULLS LAST
) AS x_pos,
FIRST_VALUE(y_pos) OVER
( PARTITION BY part
ORDER BY CASE WHEN y_pos IS NULL
THEN NULL
ELSE TIMESTAMP
END DESC NULLS LAST
) AS y_pos,
FIRST_VALUE(status) OVER
( PARTITION BY part
ORDER BY CASE WHEN status IS NULL
THEN NULL
ELSE TIMESTAMP
END DESC NULLS LAST
) AS status
FROM part_changes
;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8051 次 |
| 最近记录: |