【发布时间】:2017-11-17 04:01:06
【问题描述】:
我正在处理一个动态数据集,该数据集需要根据一系列触发器进行分解和插入。 Dataset Example
在示例中,触发器是右侧的转换列。我想要做的是添加一个额外的列,我可以按进入的第一个条目、转换和最后一个条目之间的时间戳值对这些信息进行分组。
到目前为止,我已将项目组织成 CTE,以构建这些触发器并实现这一目标。但我没有关于如何利用 CTE 进一步推动这一点的想法。本地资源告诉我我需要一个 while 循环,这些资源也不习惯将 CTE 用于他们的数据,所以我所做的对他们来说有点陌生。
看起来递归 CTE 在这里可能会有所帮助,我是新手,过去几天一直在玩它。
这是我一直在使用代码的方向:
Recursive_CTE(StemID,MasterStem,DateTimeStamp,changeover,InsertID)
as
(
SELECT
StemID
,MasterStem
,changeover
,datetimestamp
,0 as InsertID
FROM CHANGEOVER_CTE
WHERE Masterstem is null
Union ALL
SELECT
ccte.StemID
,ccte.MasterStem
,ccte.DateTimeStamp
,ccte.changeover
,case when (ccte.datetimestamp = rc.changeover)
then
rc.insertID + 1
Else
rc.InsertID
end
FROM CHANGEOVER_CTE as ccte
inner join Recursive_CTE as rc on ccte.datetimestamp = rc.changeover
还有results
问题是,一旦我达到第一个 NULL 值,CTE 的传递就会停止,我想做的是重复序列直到下一个触发器被击中,然后增加该序列并重复。
CTE 递归在这里是正确的方向吗?我可能写错了(此时我已经重写了几十次)
关于如何解决这个困境的任何建议?
【问题讨论】:
-
从 null 开始,以 null 结束.. 你为什么不抓住 min(date) 并将其放在第一行并抓住 max date 并放在最后一行飞,这应该可以解决您的问题,甚至可以制定规则,当一个人开始时,您的换班开始时,他们的轮班结束时也一样
-
以及是否可以标记适当的 sql 数据库
-
谢谢!我没想过使用最小值/最大值。这实际上解决了拥有可靠锚点的问题。我的递归仍然在第二行被杀死,但是,我认为这是因为我试图查看 datetimestamp 然后转换,当我达到第一个空值时,它们显然不匹配并且我的加入死在那里。我正在努力重写它以查看整个数据集,并且只有在它在转换中找到一个值时才更改 InsertID。
-
递归 CTE 与循环一样糟糕。此外,“触发器”这个词在 SQL 中的特定含义与您看起来的含义完全不同。
-
在此处查看我的答案 (stackoverflow.com/a/11661714/109122),了解如何在 CTE 中使用 Windowed Aggregate 函数执行此类操作(在本例中为子查询,但很容易更改为 CTE)。
标签: sql sql-server recursion common-table-expression gaps-and-islands