【问题标题】:Generate Group/Segment Identity with CTEs使用 CTE 生成组/段标识
【发布时间】:2013-02-01 15:10:59
【问题描述】:

问题是必须在 A 列(Segment)中生成一个串行 GroupID,它开始将 A 到 B 列(Indicator)的下一个 C 的行标识为一个段。 B 列是段开始(A)和段结束(C)的指示符。介于(B 或 X)之间的任何内容都应标有段 ID,包括带有 A 和 C 的行。希望它足够清楚。

File as received

Processed file with generated Group/Segment identity

我需要能最好地解决问题的建议。我有一个 .Net 循环缓慢地执行此操作,但正在尝试 CTE。请帮忙。

【问题讨论】:

  • 无论采用何种方法,我都会说您必须有一列可以排序数据。没有ID栏吗?
  • 没有保证从物理到逻辑顺序的映射。如果源数据中没有排序列,则需要逐行预处理。
  • ...通过其他进程读取文件(例如 C# 或任何可以真正打开和读取文件的程序)并了解哪一行是第一行、第二行等。一旦 SQL Server 拥有数据在表或数据源中,根据定义,它是一组无序的行。

标签: sql-server tsql recursion sql-server-2012 common-table-expression


【解决方案1】:

如果您的表格有一个 Id 列,并且您的表格被称为 [Stuff],那么这有效:

-- Set the segment values for rows where Indicator = 'A'
update [Stuff]
    set Segment = s.row
from
    (select ROW_NUMBER() OVER(ORDER BY Id) as Row, Id 
    from [Stuff] where Indicator = 'A' ) s
where
    s.Id = [Stuff].Id

-- Update the other rows
update [Stuff]
set Segment = (
    select top 1 Segment from [Stuff] s1 
    where s1.Segment is not null and s1.Id <= [Stuff].Id 
    order by Id desc
)

update [Stuff] set Segment = -1 where Indicator = '#'
update [Stuff] set Segment = 0 where Indicator = '##'

【讨论】:

  • 我当然可以有一个 ID 列来指示行号并执行 Phil 所做的事情。通过添加 ID 列,我试图查看是否可以使用不需要任何表更新和锁之类的 CTE 来完成。请让我知道你们是否能想到一种有效的技术(如果可能的话,使用 CTE )。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多