Database: Select last non-null entries

前端 未结 4 1095
你的背包
你的背包 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
    ;
    
    0 讨论(0)
  • 2021-02-19 12:12

    ruakh is right. Alternative: Write a user-defined aggregate using SQL-CLR. This aggregate can run bottom-top-top over your rows and remember the first non-null value of each column.

    You can also do this in the application. Make your program request rows in sorted order in batches of, say, 10 rows. Aggregate these batches like described above. If after the current batch is done a null-column is there get the next batch.

    0 讨论(0)
  • 2021-02-19 12:20

    For only one part this should give you an answer .. thanks to ruakh

    But I dont like this version ..

    SELECT 
        (SELECT timestamp  FROM part_changes WHERE part = $part 
        ORDER BY timestamp DESC
        LIMIT 1) as timestamp,
    
        (SELECT x-pos FROM part_changes WHERE part = $part and x-pos IS NOT NULL
        ORDER BY timestamp DESC
        LIMIT 1) as xpos,
    
        (SELECT y-pos FROM part_changes WHERE part = $part and  y-pos IS NOT NULL
        ORDER BY timestamp DESC
        LIMIT 1) as ypos,
    
        (SELECT status FROM part_changes WHERE part = $part and status IS NOT NULL
        ORDER BY timestamp DESC
        LIMIT 1)) as status
    
    0 讨论(0)
  • 2021-02-19 12:29

    list of relevant timestamps:

    select max timestamp from part_changes where x_POS is not null group by part
    

    You can make this a view: lets call this view1

    SELECT part_changes.part, part_changes.x-pos 
    FROM part_changes left join view1 on part_changes.part = view1.part
    WHERE x-pos IS NOT NULL 
     AND part_changes.timestamp = view1.timestamp 
    GROUP BY part_changes.part
    

    See where I am going? That should give you the full list for x-pos.

    0 讨论(0)
提交回复
热议问题