【问题标题】:SQL - Flag consecutive value change in columnSQL - 标记列中的连续值更改
【发布时间】:2018-04-29 09:23:12
【问题描述】:

我会尽力解释我的问题。

我有一个类似于以下内容的数据集:

Row#    CusCode Status
1   100101  Green
2   100101  Green
3   100101  Red
4   100101  Amber
5   100101  Amber
6   100101  Green
7   100101  Red
8   100101  Red
9   100101  Red
10  200909  Red
11  200909  Amber
12  200909  Green
13  200909  Red

我正在尝试将此视图作为下一步:

Row#    CusCode Status  Required
1   100101  Green   1
2   100101  Green   1
3   100101  Red 2
4   100101  Amber   3
5   100101  Amber   3
6   100101  Green   4
7   100101  Red 5
8   100101  Red 5
9   100101  Red 5
10  200909  Red 1
11  200909  Amber   2
12  200909  Green   3
13  200909  Red 4

最后一步是数据集如下所示:

CusCode Status  Required
100101  Green   1
100101  Red 2
100101  Amber   3
100101  Green   4
100101  Red 5
200909  Red 1
200909  Amber   2
200909  Green   3
200909  Red 4

请注意以下几点:

  • 我要求根据状态更改创建一个计数器,无论状态是否更改为较早的状态,目的是标记连续重复记录 - 表 2 对此进行了说明。

  • 数据集包含多条记录

  • 显示状态的顺序是最重要的,必须以相同的顺序输出(表 3 提供了此视图)。

您的帮助将不胜感激。 :)

【问题讨论】:

  • 请确定您使用的数据库。请将您的屏幕截图转换为文本,或者更好的是,给我们一个指向已填充数据的 sqlfiddle 的链接。请展示你到目前为止所做的尝试。请注意,我们不是免费的代码编写服务
  • 不要使用“数据图像”(或者我们可能会以“查询图像”作为答案......)
  • 如果维护“原始顺序”至关重要,请告诉我们哪些信息列可用于保留该顺序,因为在 SQL 表中不是“有序”的。是否有任何日期/时间列可用于此?是否有一个自动递增的整数 id 字段?这些信息很重要
  • @CaiusJard - 我已转换为文本并使用 SQL 服务器。我已经尝试使用 LAG 函数来获得“必需”文件,但没有任何乐趣。我了解您不是免费的代码编写服务,目前处于死胡同。
  • @Used_By_Already - 我希望使用“必填”字段来维护数据集的顺序。没有自动递增字段。

标签: sql sql-server-2012


【解决方案1】:

对于此阶段的第一阶段,我将使用LEAD(),然后这使我可以找到状态发生(或没有)发生变化的每一行。然后删除不需要的行,瞧!通过在幸存的行上使用ROW_NUMBER(),您可以获得最终结果。

关于“原始订单”。您永远不应依赖以可预测的顺序存储表的行。下面我使用了一个“技巧”来欺骗over clause 来应用一个实际上什么都不做的订单,因此“希望”这些行将处于所需的“原始顺序”中,但是不能保证这一点。在实践中它有效,但你真的不应该依赖它。在创建每一行时添加一个 datetime/datetime2 列。

SQL Fiddle

MS SQL Server 2014 架构设置

CREATE TABLE Table1
    ([RowNo] int, [CusCode] int, [Status] varchar(5))
;

INSERT INTO Table1
    ([RowNo], [CusCode], [Status])
VALUES
    (1, 100101, 'Green'),
    (2, 100101, 'Green'),
    (3, 100101, 'Red'),
    (4, 100101, 'Amber'),
    (5, 100101, 'Amber'),
    (6, 100101, 'Green'),
    (7, 100101, 'Red'),
    (8, 100101, 'Red'),
    (9, 100101, 'Red'),
    (10, 200909, 'Red'),
    (11, 200909, 'Amber'),
    (12, 200909, 'Green'),
    (13, 200909, 'Red')
;

删除查询

with CTE as (
  select
       *
     , lead(status) over(partition by CusCode order by (select 1)) nxt_status
  from table1
  )
delete from CTE
where status = nxt_status
;

检查查询

with CTE as (
  select
       *
     , row_number() over(partition by CusCode order by (select 1)) rn
  from table1
  )
select
*
from CTE
;

Results

| RowNo | CusCode | Status | rn |
|-------|---------|--------|----|
|     2 |  100101 |  Green |  1 |
|     3 |  100101 |    Red |  2 |
|     5 |  100101 |  Amber |  3 |
|     6 |  100101 |  Green |  4 |
|     9 |  100101 |    Red |  5 |
|    10 |  200909 |    Red |  1 |
|    11 |  200909 |  Amber |  2 |
|    12 |  200909 |  Green |  3 |
|    13 |  200909 |    Red |  4 |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 2022-01-04
    • 2023-04-03
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 2017-06-18
    相关资源
    最近更新 更多