虽然循环 SQL 没有填充完整的结果
Posted
技术标签:
【中文标题】虽然循环 SQL 没有填充完整的结果【英文标题】:While Loop SQL not populating complete results 【发布时间】:2021-08-09 02:12:18 【问题描述】:问题:迭代只发生到记录 131 并给出准确的值,之后参数 @ADE_END_DATE
返回一个 NULL
值,为什么会这样?下面是我的代码。
此外,我注意到Leave_Date
列具有NULL
值,并且迭代停止并为参数@ADE_END_DATE
返回NULL 值,其中NULL 值开始。
感谢您的帮助。
BEGIN
DECLARE @HIREDATEPlus1Yr DATETIME
DECLARE @ADE_Leave_Date DATETIME
DECLARE @ADE_End_Date DATETIME
DECLARE @ADE_Start_Date DATETIME
DECLARE @DATECAL DATETIME
DECLARE @i INT
DECLARE @j INT
DECLARE @Loop_length INT
DECLARE @ID VARCHAR(18)
-- start of loop
SET @j = 1
-- Loop length will equal to the list of all ADRs
SET @Loop_Length = (SELECT COUNT([AD_ID])
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE Status NOT IN ('MANAGER', 'TBH', 'FROZEN'))
-- Loop through each ADRs
WHILE (@j <= @Loop_length)
BEGIN
-- Loop through each ADRs
SET @i = 0
-- Find AD ID
SET @ID = (SELECT TOP 1 [AD_ID] FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE [AD_ID] NOT IN (SELECT TOP (@j-1) [AD_ID]
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE ([AD_ID] IS NOT NULL
AND Status NOT IN ('MANAGER', 'TBH', 'FROZEN'))))
-- Find the start date of the ADR
SET @ADE_Start_Date = (SELECT TOP 1 [Hire_Date]
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE [AD_ID] NOT IN (SELECT TOP (@j-1) [AD_ID]
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE ([AD_ID] IS NOT NULL
AND Status NOT IN ('MANAGER', 'TBH', 'FROZEN'))))
-- Hire date plus 1 year
SET @HIREDATEPlus1Yr = DATEADD(YEAR, 1, @ADE_Start_Date)
--Adding Leave Date
SET @ADE_Leave_Date = (SELECT TOP 1 [LEAVE_DATE]
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE [AD_ID] NOT IN (SELECT TOP (@j-1) [AD_ID]
FROM [DS_ADHOC_MOPs].[ADE].[List]
WHERE ([AD_ID] IS NOT NULL
AND Status NOT IN ('MANAGER', 'TBH', 'FROZEN'))))
-- Set a temporary variable which will be 1 year from now. Use the Date ADD formulae to start date, if they are leaver before one year then add leave date (Use IF): DONE
-- Put everything inside the while loop and add opportunity selecting to it.
IF @ADE_Leave_Date IS NULL
SET @ADE_End_Date = DATEADD(YEAR, 1, @ADE_Start_Date)
ELSE IF @HIREDATEPlus1Yr < @ADE_Leave_Date
SET @ADE_End_Date = DATEADD(YEAR, 1, @ADE_Start_Date)
ELSE
SET @ADE_End_Date = @ADE_Leave_Date
SET @DATECAL = datediff(DAY, @ADE_Start_Date, @ADE_End_Date)
SET @j = @j + 1
UPDATE #TEMPTABLEEEE
SET [@ADE_End_Date] = @ADE_End_Date
WHERE @ID = AD_ID
END
SELECT * FROM #TEMPTABLEEEE
END
【问题讨论】:
这适用于哪个 RDBMS?请添加标签以指定您使用的是mysql
、postgresql
、sql-server
、oracle
还是db2
- 或其他完全不同的东西。
它来自 SQL-Server。
【参考方案1】:
我不确定您为什么要使用 WHILE 循环。看起来这段代码可以大大简化。 SQL 是一种基于集合的语言。只要有可能,您应该尝试将您的数据作为一个整体来处理,而不是将其分解为逐行评估。
这能满足您的需要吗?如果表中的每个 AD_ID 有不止一行,则需要获取 MAX() 或 MIN() Hire_Date/LEAVE_DATE。要改进答案,请考虑提供示例数据。
UPDATE t
SET [@ADE_End_Date] = ed.ADE_EndDate
FROM #TEMPTABLEEEE AS t
INNER JOIN (
SELECT AD_ID
,CASE
WHEN LEAVE_DATE IS NULL THEN DATEADD(YEAR,1,Hire_Date)
WHEN DATEADD(YEAR,1,Hire_Date) < LEAVE_DATE THEN DATEADD(YEAR,1,Hire_Date)
ELSE LEAVE_DATE
END AS ADE_EndDate
FROM DS_ADHOC_MOPs.ADE.List
WHERE Status NOT IN ('MANAGER', 'TBH', 'FROZEN')
) AS ed ON t.AD_ID = ed.AD_ID
【讨论】:
以上是关于虽然循环 SQL 没有填充完整的结果的主要内容,如果未能解决你的问题,请参考以下文章