2014-11-28 5 views
0

ВЫБРАТЬ YMD, значение от таблицыФункции, чтобы получить последнее значение месяца, SQL

YMD   Value  
2014-01-01 100  
2014-02-01 200  
2014-03-01 300  
2014-04-01 250  

Я хочу использовать скаляр или таблицу функцию, чтобы получить значение от предыдущего месяца:

SELECT, YMD, Value, Функция (ГМД), как prev1month из таблицы

YMD   Value  prev1month 
2014-01-01 100   NULL 
2014-02-01 200   100 
2014-03-01 300   200 
2014-04-01 250   300 

Давайте добавить еще одно условие:

ВЫБОР Y MD, значение, функция (ГМД), как prev1month ИЗ таблицы

YMD   Value  prev1month prev1year 
2013-01-01  50   NULL   
2014-01-01 100   NULL   50 
2014-02-01 200   100 
2014-03-01 300   200 
2014-04-01 250   300 

Я попытался следующие, но получаю ошибки при дальнейших расчетах:

SELECT YMD, Value 
FROM TABLE as t1 
INNER JOIN TABLE 2 as t2 
on t2.YMD = DATEADD(m,-1, t1.YMD) 

Любые предложения?

I'm с помощью SQL 2008 R2

+1

вы используете SQL 2012 или SQL Server 2008? – radar

+1

«SQL» - это стандарт, который реализует большинство СУБД. SQL Server является продуктом Microsoft RDBMS. Пожалуйста, отметьте свой вопрос с помощью РСУБД, которые вы используете. – Allan

+1

Я поставил вопрос 'sql-server' на основе использования' dateadd() '. –

ответ

2

Стандарт SQL-lag() имеет функциональность, что делает это. Вы также можете написать запрос, используя коррелированный подзапрос. Для этого требуется получить одну строку из подзапроса. Вот метод, который работает в базах данных, которые используют top:

select ymd, value, 
     (select top 1 value 
     from table t2 
     where t2.ymd < t.ymd 
     order by t2.ymd desc 
     ) as prev_value 
from table t1; 

Использование lag(), было бы:

select ymd, value, lag(value) over (order by ymd) as prev_value 
from table t; 

Это работает в SQL Server 2012+.

2

Если вы используете MS SQL Server 2012+ вы можете получить доступ к предыдущим строкам в наборе, используя с функцией LAG() окна:

SELECT YMD, Value, LAG(value) OVER (ORDER BY YMD) as prev1month FROM Table 

Тем же функциональность (отставание) в некоторой другой СУБД тоже.

Редактировать: поскольку вы используете более старую версию без поддержки запаздывания, вам придется использовать другой метод, подобный описанному Гордоном Линоффом.

0
select t.*,Prev.Value 
from Table t 
    Outer Apply (Select top 1 Value 
       From Table P 
       Where P.Dt < t.Dt 
       Order by P.Dt Desc) Prev 
0

Другой способ сделать это, используя Left Join. Это должно работать с SQL SERVER 2005+

CREATE TABLE #test 
    (YMD DATE,Value INT) 

INSERT #test 
VALUES('2014-01-01',100), 
     ('2014-02-01',200), 
     ('2014-03-01',300), 
     ('2014-04-01',250); 

WITH cte 
    AS (SELECT Row_number()OVER (ORDER BY ymd) Rn, 
       * 
     FROM #test) 
SELECT a.YMD, 
     a.value, 
     b.value As Prev_Value 
FROM cte a 
     LEFT JOIN cte b 
       ON a.Rn = b.Rn + 1 

Результат

+-----------+-------+-------------+ 
| YMD  | value | Prev_Value | 
+-----------+-------+-------------+ 
|2014-01-01 | 100 | NULL  | 
|2014-02-01 | 200 | 100  | 
|2014-03-01 | 300 | 200  | 
|2014-04-01 | 250 | 300  | 
+-----------+-------+-------------+