【问题标题】:Check previous and next record检查上一条和下一条记录
【发布时间】:2019-01-15 11:55:21
【问题描述】:

我正在尝试比较不同时期的不同成本。但是我不知道如何将单个记录与之前和之后的记录进行比较。当记录的成本与之前和之后的记录相同时,我需要的是数据集中的“是”或“否”。

我的数据集如下所示:

+--------+-----------+----------+------------+-------+-----------+
| Client | Provision | CAK Year | CAK Period | Costs | Serial Nr |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2017   |     13     |  150  |     1     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2018   |     1      |  200  |     2     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2018   |     2      |  170  |     3     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2018   |     3      |  150  |     4     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2018   |     4      |  150  |     5     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    210    |   2018   |     5      |  150  |     6     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    689    |   2018   |     1      |  345  |     1     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    689    |   2018   |     2      |  345  |     1     |
+--------+-----------+----------+------------+-------+-----------+
|   1    |    689    |   2018   |     3      |  345  |     1     |
+--------+-----------+----------+------------+-------+-----------+

到目前为止我尝试过的:

CASE
WHEN Provision = Provision
AND Costs = LEAD(Costs, 1, 0) OVER(ORDER BY CAK Year, CAK Period)
AND Costs = LAG(Costs, 1, 0) OVER(ORDER BY CAK Year, CAK Period)
THEN 'Yes
ELSE 'No'
END

我的预期结果:

+--------+-----------+----------+------------+-------+-----------+--------+
| Client | Provision | CAK Year | CAK Period | Costs | Serial Nr | Result |
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2017   |     13     |  150  |     1     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2018   |     1      |  200  |     2     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2018   |     2      |  170  |     3     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2018   |     3      |  150  |     4     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2018   |     4      |  150  |     5     |  Yes
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    210    |   2018   |     5      |  150  |     6     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    689    |   2018   |     1      |  345  |     1     |   No
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    689    |   2018   |     2      |  345  |     1     |  Yes
+--------+-----------+----------+------------+-------+-----------+--------+
|   1    |    689    |   2018   |     3      |  345  |     1     |   No
+--------+-----------+----------+------------+-------+-----------+--------+

因为我没有得到预期的结果,你们可以进一步帮助我吗?

【问题讨论】:

  • 你在'Yes 之后错过了'(但我想这是一个错字)并且Provision = Provision 可以省略,这总是正确的(但它没有害处)。您在此处显示记录的顺序与OVER 子句中的顺序不同。例如。 CAK Period 1 for 2018 不相邻。也许这就是问题所在?
  • 查看与窗口函数一起使用的OVER() 子句。 docs.microsoft.com/es-es/sql/t-sql/queries/…

标签: tsql lag lead


【解决方案1】:

您需要添加 partition by Provision 否则您的 laglead 排序将运行在所有 Provision 值中:

declare @d table(Client int,Provision int,CAKYear int, CAKPeriod int, Costs int, SerialNr int);
insert into @d values
 (1,210,2017,13,150,1)
,(1,210,2018,1,200,2)
,(1,210,2018,2,170,3)
,(1,210,2018,3,150,4)
,(1,210,2018,4,150,5)
,(1,210,2018,5,150,6)
,(1,689,2018,1,345,1)
,(1,689,2018,2,345,1)
,(1,689,2018,3,345,1);

select *
        ,case when Provision = Provision
                and Costs = lead(Costs, 1, 0) over(partition by Provision order by CAKYear, CAKPeriod)
                and Costs = lag(Costs, 1, 0) over(partition by Provision order by CAKYear, CAKPeriod)
            then 'Yes'
            else 'No'
            end as Result
from @d
order by Provision
        ,CAKYear
        ,CAKPeriod;

输出

+--------+-----------+---------+-----------+-------+----------+--------+
| Client | Provision | CAKYear | CAKPeriod | Costs | SerialNr | Result |
+--------+-----------+---------+-----------+-------+----------+--------+
|      1 |       210 |    2017 |        13 |   150 |        1 | No     |
|      1 |       210 |    2018 |         1 |   200 |        2 | No     |
|      1 |       210 |    2018 |         2 |   170 |        3 | No     |
|      1 |       210 |    2018 |         3 |   150 |        4 | No     |
|      1 |       210 |    2018 |         4 |   150 |        5 | Yes    |
|      1 |       210 |    2018 |         5 |   150 |        6 | No     |
|      1 |       689 |    2018 |         1 |   345 |        1 | No     |
|      1 |       689 |    2018 |         2 |   345 |        1 | Yes    |
|      1 |       689 |    2018 |         3 |   345 |        1 | No     |
+--------+-----------+---------+-----------+-------+----------+--------+

【讨论】:

  • 该死的传奇
  • @miltenburger 如果您有多个Client,那么您可能还想在客户端进行分区。
  • @HABO,我当然有更多的客户,但每个条款都是独一无二的,这就足够了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-02
  • 1970-01-01
  • 2013-03-26
相关资源
最近更新 更多