我想要一些 SQL 语法来检查值是否与下面的值不同

I would like some SQL syntax for checking if the value differs from the one below it

我想要一些 SQL (Sql Server2008R2) 语法来检查值(tMonth 列)是否与它下面的值不同,第二行的 %Change 应该留空,请参阅下面的示例以及预期内容:

+-------+-------+---------+---------+----------+
| Month | tYear | Indices | %Change | Expected |
+-------+-------+---------+---------+----------+
|    01 |  2016 | 166.78  |  NULL   |          |
|    01 |  2017 | 190.51  |  14.2   |   14.2   |
|    01 |  2018 | 197.23  |   3.5   |    3.5   |
|    02 |  2016 | 166.76  | -15.5   |          |
|    02 |  2017 | 188.99  |  13.3   |   13.3   |
|    02 |  2018 | 198.20  |   4.9   |    4.9   |
|    03 |  2016 | 167.34  | -15.6   |          |
|    03 |  2017 | 190.06  |  13.6   |   13.6   |
|    03 |  2018 | 194.60  |   2.4   |    2.4   |
|    04 |  2016 | 169.89  | -12.7   |          |
|    04 |  2017 | 194.24  |  14.3   |   14.3   |
|    04 |  2018 | 203.99  |   5.0   |    5.0   |
|    05 |  2016 | 170.24  | -16.5   |          |
|    05 |  2017 | 196.83  |  15.6   |   15.6   |
|    06 |  2016 | 172.54  | -12.3   |          |
+-------+-------+---------+---------+----------+

使用伪编程代码:

IF tMonth1 <> tMonth2
     Replace %Change with NULL
ELSE
    %Change remains the way it is.

在此先感谢您的帮助。

由于仅从 SQL Server 2012 开始支持 LEAD 和 LAG,因此我建议使用自连接和 row_number 功能。检查这个例子:

DECLARE @t TABLE(
  tMonth NVARCHAR(2),
  tYear INT,
  pChange DECIMAL(5,2)
)

INSERT INTO @t VALUES
 ('01', 2016, NULL)
,('01', 2017, 14.2)
,('01', 2018,  3.5)
,('02', 2016,-15.5)
,('02', 2017, 13.3)
,('02', 2018,  4.9)
,('03', 2016,-15.6)
,('03', 2017, 13.6)
,('03', 2018,  2.4)
,('04', 2016,-12.7)
,('04', 2017, 14.3)
,('04', 2018,  5.0)
,('05', 2016,-16.5)
,('05', 2017, 15.6)
,('06', 2016,-12.3)

;WITH cte AS(
SELECT  tMonth,
        tYear,
        pChange,
        ROW_NUMBER() OVER (ORDER BY tMonth, tYear) rn
  FROM @t
)
SELECT  c1.tMonth,
        c1.tYear,
        c1.pChange,
        CASE WHEN c1.tMonth != c2.tMonth THEN NULL ELSE c1.pChange END AS pChangeNew
  FROM cte AS c1
  LEFT JOIN cte AS c2 ON c1.rn = c2.rn+1

使用自我 full outer joinrow_number:

declare @tmp table(tMonth varchar(2), tYear int, Indices decimal(18,6), [%Change]  decimal(18,6))
insert into @tmp values
 ('01', 2016, 166.78,  NULL)
,('01', 2017, 190.51,  14.2)
,('01', 2018, 197.23,   3.5)
,('02', 2016, 166.76, -15.5)
,('02', 2017, 188.99,  13.3)
,('02', 2018, 198.20,   4.9)
,('03', 2016, 167.34, -15.6)
,('03', 2017, 190.06,  13.6)
,('03', 2018, 194.60,   2.4)
,('04', 2016, 169.89, -12.7)
,('04', 2017, 194.24,  14.3)
,('04', 2018, 203.99,   5.0)
,('05', 2016, 170.24, -16.5)
,('05', 2017, 196.83,  15.6)
,('06', 2016, 172.54, -12.3)
select t1.*, case when t1.tMonth <> t2.tMonth then null else t1.[%Change] end as [%Change_replace]  
from (
    select ROW_NUMBER() OVER (ORDER BY tmonth) as id ,* from @tmp
) t1
full outer join( 
    select ROW_NUMBER() OVER (ORDER BY tmonth) as id ,* from @tmp
) t2 
on t1.id = t2.id+1
where t1.id is not null

结果:

从你的数据来看,你只想:

select t.*,
       (case when row_number() over (partition by month order by year) > 1
             then pChange
        end) as expected
from t;