Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Clever puzzle.</p> <p>You need to reconstruct all the time spans. To do this, I take out all the dates from the price ranges and reconstruct the possible date ranges.</p> <pre><code>with alldates as (select d.*, ROW_NUMBER() over (partition by productkey order by thedate) as seqnum from ((select productkey, BeginDate as thedate from prices) union all (select productkey, enddate as thedate from prices) ) d ), datepair as (select d1.productkey, d1.thedate as BeginDate, d2.thedate as EndDate from alldates d1 left outer join alldates d2 on d1.seqnum = d2.seqnum - 1 and d1.productKey = d2.productKey ) select dp.productkey, dp.BeginDate, dp.EndDate, SUM(p.price) from datepair dp join prices p on dp.productkey = p.productkey and dp.BeginDate &gt;= p.BeginDate and dp.EndDate &lt;= p.EndDate group by dp.productkey, dp.BeginDate, dp.EndDate order by 1, 2, 3 </code></pre> <p>I've thought about this some more. The basic idea above is correct. The basic idea is to break up the time dimension into intervals where the list and discount is constant over the entire interval. The question is how to create these intervals, which are in the datepairs alias.</p> <p>These intervals have just a few rules:</p> <ul> <li>A datepair interval can begin when any time period begins.</li> <li>A datepair interval can begin one day after any time period ends.</li> <li>A datepair interval can end when any time period ends</li> <li>A datepair interval can end one day before any time period begins</li> </ul> <p>Once we have the intervals, it is a simple matter to join in the appropriate list price and discounts for that period. The following query uses this logic:</p> <pre><code>with begindates as (select distinct productKey, thedate from ((select productkey, BeginDate as thedate from prices) union all (select productkey, dateadd(d, 1, enddate) as thedate from prices) ) d ), enddates as (select distinct productKey, thedate from ((select productkey, DATEADD(d, -1, begindate) as thedate from prices) union all (select productkey, enddate as thedate from prices) ) d ), datepair as (select * from (select d1.productkey, d1.thedate as BeginDate, MIN(d2.thedate) as EndDate from begindates d1 left outer join enddates d2 on d1.productKey = d2.productKey and d1.thedate &lt; d2.thedate group by d1.productkey, d1.thedate ) t where BeginDate &lt;&gt; EndDate ) select dp.productkey, dp.BeginDate, dp.EndDate, SUM(p.price) from datepair dp join prices p on dp.productkey = p.productkey and dp.BeginDate &gt;= p.BeginDate and dp.EndDate &lt;= p.EndDate group by dp.productkey, dp.BeginDate, dp.EndDate order by 1, 2, 3 </code></pre>
    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.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      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