Note that there are some explanatory texts on larger screens.

plurals
  1. POTime series querying in Postgres
    primarykey
    data
    text
    <p>This is a follow on question from @Erwin's answer to <a href="https://stackoverflow.com/a/14877465/79790">Efficient time series querying in Postgres</a>. </p> <p>In order to keep things simple I'll use the same table structure as that question</p> <pre><code>id | widget_id | for_date | score | </code></pre> <p>The original question was to get score for each of the widgets for every date in a range. If there was no entry for a widget on a date then show the score from the previous entry for that widget. The solution using a cross join and a window function worked well if all the data was contained in the range you were querying for. My problem is I want the previous score even if it lies outside the date range we are looking at.</p> <p>Example data:</p> <pre><code>INSERT INTO score (id, widget_id, for_date, score) values (1, 1337, '2012-04-07', 52), (2, 2222, '2012-05-05', 99), (3, 1337, '2012-05-07', 112), (4, 2222, '2012-05-07', 101); </code></pre> <p>When I query for the range May 5th to May 10th 2012 (ie <code>generate_series('2012-05-05'::date, '2012-05-10'::date, '1d')</code>) I would like to get the following:</p> <pre><code>DAY WIDGET_ID SCORE May, 05 2012 1337 52 May, 05 2012 2222 99 May, 06 2012 1337 52 May, 06 2012 2222 99 May, 07 2012 1337 112 May, 07 2012 2222 101 May, 08 2012 1337 112 May, 08 2012 2222 101 May, 09 2012 1337 112 May, 09 2012 2222 101 May, 10 2012 1337 112 May, 10 2012 2222 101 </code></pre> <p>The best solution so far (also by @Erwin) is:</p> <pre><code>SELECT a.day, a.widget_id, s.score FROM ( SELECT d.day, w.widget_id ,max(s.for_date) OVER (PARTITION BY w.widget_id ORDER BY d.day) AS effective_date FROM (SELECT generate_series('2012-05-05'::date, '2012-05-10'::date, '1d')::date AS day) d CROSS JOIN (SELECT DISTINCT widget_id FROM score) AS w LEFT JOIN score s ON s.for_date = d.day AND s.widget_id = w.widget_id ) a LEFT JOIN score s ON s.for_date = a.effective_date AND s.widget_id = a.widget_id ORDER BY a.day, a.widget_id; </code></pre> <p>But as you can see in this <a href="http://www.sqlfiddle.com/#!12/1cb5c/1/0" rel="nofollow noreferrer">SQL Fiddle</a> it produces null scores for widget 1337 on the first two days. I would like to see the earlier score of 52 from row 1 in its place.</p> <p>Is it possible to do this in an efficient way? </p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload