当前位置: 首页 > 面试题库 >

数据库:选择最后一个非空条目

唐高卓
2023-03-14
问题内容

这是我一直在绞尽脑汁的一个问题。假设我有一个表,该表具有一系列时间戳和一个零件号作为主键。该表存储增量更改,这意味着对于每个时间戳记,如果字段更改,则记录该更改。如果该字段保持不变,则对于新的时间戳,该字段为NULL。这是基本思想。

 part | timestamp | x-pos | y-pos | status
------+-----------+-------+-------+--------
 a5   |       151 |     5 |    15 |      g
 a5   |       153 |  NULL |    17 |   NULL

(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))

但这将返回单个列,这意味着我可以使用分组依据进行组织。

必须有一种更优雅的处理方式,例如以创造性的方式使用COALESCE或IS NULL。但是我被困住了,无法解决。有人知道吗?

不,我无法更改数据库结构。

编辑:ruakh有一个正确的主意。现在唯一的问题是按部分分组。我似乎LIMIT 1无法解决按多个部分进行分组的问题。有任何想法吗?

mdahlman,我不太了解postgresql中的分析功能。因此,如果该解决方案比复杂的查询要容易,那么一定要发表您的想法。

编辑2:谢谢大家的帮助。我想我对我需要做的事情有足够的了解。


问题答案:

UNION听起来好像不是真的要在字段列表中使用子查询,而不是使用a 。也就是说,而不是(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
;

但是在这一点上,我真的会考虑编写存储过程

或者:

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
;


 类似资料:
  • 我正试图从数据库表中检索最后一条记录。我的查询如下: MID是员工id代码,主键是id。 因为主键(在我的例子中)是整数,并且在每次插入记录时自动递增,所以我试图在主键的基础上获取最后一条记录,因为与其他记录相比,最后一条记录将具有最高值的主键。 但是我不能制定如何给出条件指定最高值的主键。我需要添加主键,如下所示:

  • 问题内容: 我的目标是在最后一个CSS上使用CSS ,但是这样做不是。 如何 只 选择最后一个孩子? 问题答案: 该伪类仍然无法可靠地跨浏览器使用。特别是,InternetExplorer<9和Safari<3.2绝对不支持它,尽管Internet Explorer 7和Safari 3.2 确实 支持。 最好的选择是向该项目显式添加一个(或类似的)类,然后应用。

  • 问题内容: 我正在插入一条记录,我想使用插入的最后一条记录的ID。这是我尝试过的: 我收到错误消息: SQL语法错误;请查看与您的MySQL服务器版本相对应的手册,以在“ SELECT LAST_INSERT_ID()”附近使用正确的语法。谁能告诉我我的错误在哪里?谢谢! 问题答案: 签出mysql_insert_id() 在mysql_query()命令中执行INSERT语句后运行该函数时,其结

  • 问题内容: 我已经做了一些寻找该问题答案的搜索,但是我能弄清楚的是: 在我看来,这似乎很古怪,又不合蟒蛇风(而且很慢?)。 在不指定列名的情况下,为pandas数据框中的最后一列选择数据的最简单方法是什么? 问题答案: 使用iloc并针对最后一列()选择所有行():

  • 问题内容: 我有一个包含4列的表格:项目,年份,月份,金额。Amount的某些值是null,当发生这种情况时,我想用以前的非null的Amount值来填充这些值。当只有一个空值时,我可以使用LAG函数轻松地做到这一点,但是当连续有多个空值时,我不确定如何处理它。以下是该表的外观示例,其中添加了要在查询中添加的内容的列: 我有两个想法,我似乎无法投入工作来实现自己想要的东西。首先,我要使用LAG,但

  • 命令用于选择数据库,如果想在一个数据库上工作,比如:创建表,查询表,更新,创建存储过程等等,那么首先需要选择一个目标数据库。 示例 假设在MariaDB数据库服务器中,存在有多个数据库,我们必须选择一个特定的数据库。 例如,在下图中显示了多个数据库: 这里我们将使用数据库来创建表等。所以需要使用以下命令。 在执行上面查询语句后,就已经选择数据库。之后就可以在里面创建表等数据对象了。执行上面查询语句