我想要一些 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 join
和 row_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;
我想要一些 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 join
和 row_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;