1

I am trying to replace null values with previous available record. i try to search answer for this query on stakeoverflow however, those answers are quite confusing hence looking for simple answer alone with explaination.

tried to get the previous value of the null value but it shows 0 records using this query :

CREATE TABLE messages (
channelid INTEGER,
messageid INTEGER,
timesent DATETIME
);
INSERT INTO messages (channelid, messageid, timesent)
VALUES (10, 2, '2022-07-04 04:04');

INSERT INTO messages (channelid, messageid, timesent)
VALUES (10, 5, '2022-07-04 08:04');

INSERT INTO messages (channelid, messageid, timesent)
VALUES (10, 3, NULL);

INSERT INTO messages (channelid, messageid, timesent)
VALUES (10, 7, '2022-07-04 08:04');

`SELECT timesent 
 FROM messages 
 WHERE timesent < messages.timesent and not null `

SQL fiddle

2
  • According to which column we will get the previous row ? Commented Jan 2, 2023 at 9:01
  • For fetching previous timesent record the record should be there in some Table like an audit table/History table if not the previous values should be there in some column so the question is confusing here for me atleast Commented Jan 2, 2023 at 10:00

1 Answer 1

1

Supposing that the messageid column specifies the order of messages by which we can define what the previous value is, you can use a subquery as the following:

select channelid, messageid, 
  (
    select timesent from messages t2 
    where t2.channelid = t1.channelid and 
          t2.messageid <= t1.messageid and 
          t2.timesent is not null 
    order by t2.messageid desc limit 1
  ) timesent
from messages t1
order by messageid

Another approch, you can use the conditional max window function to define groups that connect the null values with the last not null value as the following:

select channelid, messageid, 
       coalesce(timesent, max(timesent) over (partition by channelid, grp)) as timesent
from
  (
    select *,
      max(case when timesent is not null then messageid end) over
         (partition by channelid order by messageid) as grp
    from messages 
  ) t
order by messageid

And if the timesent value will not be decreased with the increasing of the messageid value, then you can use the running max window function as the following:

select channelid, messageid, timesent_not_null as timesent
from
(
  select *, 
    max(timesent) over (partition by channelid order by messageid) timesent_not_null
  from messages
) t
-- where some condition (if needed)
order by messageid

See demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.