Question

Suppose I had the following table in SQL Server:

Date         ColA         ColB
1/1/2013     Val1A        Val1B
1/1/2013     Val2A        NULL
1/1/2013     Val3A        Val3B
1/2/2013     Val1A        NULL
1/2/2013     Val2A        Val4B

And, I'm looking to see the day-over-day changes for ColB - Which, in this case could look as follows:

Date         ColA         ColB_Today       ColB_Prev_Day
1/2/2013     Val1A        NULL             Val1B
1/2/2013     Val2A        Val4B            NULL
1/2/2013     Val3A        NULL             Val3B

So, to do this I created a fairly complex query (joining the table to itself) that has a single input variable and a calculated variable looking as follows:

DECLARE @Date Date = '1/2/2013', @PrevDay Date;
SET @PrevDay = (Select TOP 1 Date from MyTable where Date < @Date order BY Date desc);

SELECT
  @Date as 'Date',
  T1.ColA,
  T1.ColB as ColB_Today,
  T2.ColB as ColB_Prev_Day
FROM
  (SELECT * FROM MyTable where Date = @Date) T1,
 FULL OUTER JOIN
  (SELECT * FROM MyTable where Date = @PrevDay) T2
 ON
  T1.ColA = T2.ColA

Which is what I'm looking for.

Now, I'd like to be able to convert this into a View (with no parameters being passed) rather than this paramaterized query.

I hope that what I'm looking to do makes sense... In other words, the view would have the columns Date, ColA, ColB_Today & ColB_Prev_Day and it simply pulls the data from the table to create the same result without having to paramaterize date (simply, based upon the dates available in the table) - My biggest challenge seems to be the Val3A row above which has a value only for one of the 2 dates, not both...

Any thoughts???

Thanks!!

Was it helpful?

Solution

you can use something ugly like this:

with cte_dates as (
    select distinct [Date] from MyTable
), cte_vals as (
    select distinct ColA from MyTable
)
select
    d.[Date],
    v.ColA,
    T1.ColB as ColB_Today,
    T2.ColB as ColB_Prev_Day
from cte_dates as d
    cross join cte_vals as v
    left outer join MyTable as T1 on T1.ColA = v.ColA and T1.[Date] = d.[Date]
    outer apply (
        select top 1 TT.ColB
        from MyTable as TT
        where TT.ColA = v.ColA and TT.[Date] < d.[Date]
        order by TT.[Date] desc
    ) as T2

=> sql fiddle demo

It's hard to do better until I know more about your data. Do you have gaps between dates in your table?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top