Database: Select last non-null entries

前端 未结 4 1082
你的背包
你的背包 2021-02-19 11:47

Here\'s a question I\'ve been racking my brain over. Let\'s say I have a table that has a series of timestamps and a part number as the primary key. The table stores incremental

4条回答
  •  死守一世寂寞
    2021-02-19 12:10

    Rather than using a UNION, it sounds like you really want subqueries in the field list. That is, instead of (SELECT ...) UNION (SELECT ...) UNION (SELECT ...), you want SELECT (SELECT ...), (SELECT ...), (SELECT ...).


    For example:

    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
    ;
    

    But at this point I would really consider writing a stored procedure.


    Alternatively:

    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
    ;
    

提交回复
热议问题