SQL Server:循环遍历每个(PARTITION BY ...)元素的过程或函数
Posted
技术标签:
【中文标题】SQL Server:循环遍历每个(PARTITION BY ...)元素的过程或函数【英文标题】:SQL Server : procedure or function to loop over each (PARTITION BY ...) element 【发布时间】:2020-09-02 12:32:46 【问题描述】:我正在通过实际示例学习 SQL 语法。我有下表:
CREATE TABLE [dbo].[Orders_tmp_test]
(
department_id VARCHAR(4),
rank_pr_co INT,
starting_date DATE,
end_date DATE
)
INSERT INTO [dbo].[Orders_tmp_test]
SELECT '1001', 1, '2019/04/01', '2020/02/01'
UNION ALL
SELECT '1001', 2, '2020/01/31', '2020/04/30'
UNION ALL
SELECT '1001', 3, '2020/03/01', '2020/03/01'
UNION ALL
SELECT '1001', 4, '2020/03/31', '2020/05/31'
UNION ALL
SELECT '1002', 1, '2019/03/01', '2020/02/01'
UNION ALL
SELECT '1002', 2, '2020/01/01', '2020/04/01'
每个部门都有几个项目。项目按“rank_pr_co”提供的顺序执行。当前项目尚未结束,但给定部门的另一个项目已经开始时,称为冲突。我想修改将解决所有冲突的项目的“starting_date”和“end_date”。项目的长度是固定的。对于“starting_date”=“end_date”的项目,我想保持原样。在这种情况下,我想解决上一个项目和下一个项目之间的冲突。
最后我想要下表:
'1001', 1, '2019/04/01', '2020/02/01'
'1001', 2, '2020/02/01', '2020/05/01'
'1001', 3, '2020/03/01', '2020/03/01'
'1001', 4, '2020/05/01', '2020/07/01'
'1002', 1, '2019/03/01', '2020/02/01'
'1002', 2, '2020/02/01', '2020/05/01'
我尝试创建标量函数并将其转换为(按...分区)元素,但它不起作用并返回错误:
消息 4113,第 16 级,状态 1,第 3 行 函数“dbo.ideal_schema”不是有效的窗口函数,不能与 OVER 子句一起使用。
有人知道如何得出决赛桌吗?
【问题讨论】:
我看不出您的示例数据如何解决冲突。 用户定义的函数不能有窗口。只有特定的聚合和分析 T-SQL 函数可以。 @GordonLinoff 感谢您的快速响应。在新表中, ('1001',2) 是在上一个项目 ('1001',1) 结束时开始的。这正在解决这些项目相互冲突的时间表。 @baraban55 。 . .但它在下一个项目之后结束。 @GordonLinoff 没错!这是主要的困难。 ('1001', 3) 是特殊的。它开始和结束相同的日期(立即完成)。这就是为什么我解决了 ('1001', 2) 和 ('1001', 4) 之间的冲突并保留 ('1001', 3) 的原因。 【参考方案1】:如果您希望项目中没有重叠日期并且结束日期不包含在内,那么只需使用lead()
:
select t.*,
lead(end_date, 1, end_date) over (partition by project_id order by start_date) as imputed_end_date
from Orders_tmp_test t;
注意:这不故意使用排序列。对于在日期和指定顺序彼此无关的极端情况下该怎么做,您必须有更多解释。
注意:如果你真的想update
表,这可以很容易地合并到update
语句中。我认为没有理由为此编写用户定义的函数。您可能需要一个视图,如果您希望在查询表时获得此信息。
【讨论】:
似乎“领导”功能可能是正确的方向。但是,它并不能解决一些问题。 “starting_date”和“end_date”都应该更改。此外,如果“starting_date”="end_date",那么它根本不应该改变。以上是关于SQL Server:循环遍历每个(PARTITION BY ...)元素的过程或函数的主要内容,如果未能解决你的问题,请参考以下文章