检索非空值查询,返回前一个值

问题描述 投票:0回答:1

我编写了以下查询,该查询对于 OccupancyID 182 返回正确的值。但是,对于日期为 2024 年 3 月 1 日的 OccupancyID 3313,它返回 150015,而不是 100812。

该查询试图满足返回跨日期期间最新的 CustomerVoice_RepairsSatisfactionFeedbackID 的需求。对于 OccupancyID 3313,FeedbackID 150015 在 2023 年 11 月 1 日和 2023 年 12 月 01 日有效,但随后出现了 100812,并且是应该从那时起继续使用的 ID,直到再次更改为止。

有人能看出我哪里出错了吗?

预期结果

占用ID 月初一 CustomerVoice_RepairsSatisfactionFeedbackID 上一个NonNULLCustomerVoice_RepairsSatisfactionFeedbackID
182 2023-10-01
182 2023-11-01 100571
182 2023-12-01 100571
182 2024-01-01 100571
182 2024-02-01 100571
182 2024-03-01 100571
3313 2023-10-01
3313 2023-11-01 150015
3313 2023-12-01 150015
3313 2024-01-01 100812 150015
3313 2024-02-01 100812
3313 2024-03-01 100812(目前显示为150015,这是错误的)
drop table if exists #temp2

CREATE TABLE #temp2
(
    [FirstDayOfMonth] [date] NOT NULL,
    [OccupancyID] [int] NULL,
    [CustomerVoice_RepairsSatisfactionFeedbackID] [int] NULL,
    [RowNumber] [bigint] NULL
)
GO
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-10-01' AS Date), 3313, NULL, 1)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-11-01' AS Date), 3313, 150015, 2)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-12-01' AS Date), 3313, NULL, 3)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-01-01' AS Date), 3313, 100812, 4)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-02-01' AS Date), 3313, NULL, 5)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-03-01' AS Date), 3313, NULL, 6)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-10-01' AS Date), 182, NULL, 1)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-11-01' AS Date), 182, 100571, 2)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2023-12-01' AS Date), 182, NULL, 3)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-01-01' AS Date), 182, NULL, 4)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-02-01' AS Date), 182, NULL, 5)
INSERT #temp2 ([FirstDayOfMonth], [OccupancyID], [CustomerVoice_RepairsSatisfactionFeedbackID], [RowNumber]) VALUES (CAST(N'2024-03-01' AS Date), 182, NULL, 6)
GO

;WITH CTE AS 
(
    SELECT
        FirstDayOfMonth, 
        OccupancyID, 
        CustomerVoice_RepairsSatisfactionFeedbackID,
        RowNumber,
        LAG(CustomerVoice_RepairsSatisfactionFeedbackID) OVER(PARTITION BY OccupancyID ORDER BY FirstDayOfMonth) AS Lag_Value,
        ROW_NUMBER() OVER(PARTITION BY OccupancyID ORDER BY FirstDayOfMonth) AS RN,
        CASE WHEN CustomerVoice_RepairsSatisfactionFeedbackID IS NOT NULL THEN 1 ELSE 0 END AS Flag            
    FROM 
        #temp2
)
SELECT 
    OccupancyID, 
    FirstDayOfMonth, 
    CustomerVoice_RepairsSatisfactionFeedbackID,
    CASE 
        WHEN Lag_Value IS NULL THEN PreviousCustomerVoice_RepairsSatisfactionFeedbackID
        ELSE Lag_Value 
    END AS PreviousNonNULLCustomerVoice_RepairsSatisfactionFeedbackID
FROM 
(
    SELECT *,
    (
        SELECT 
            TOP(1) CustomerVoice_RepairsSatisfactionFeedbackID 
        FROM 
            CTE c
        WHERE 
            c.Flag = 1 AND 
            c.RN < a.RN AND 
            c.OccupancyID = a.OccupancyID
    ) AS PreviousCustomerVoice_RepairsSatisfactionFeedbackID
    FROM CTE 
a) a
sql sql-server t-sql sql-server-2017
1个回答
0
投票

您的问题的解决方案:

;WITH CTE AS 
(
    SELECT
        FirstDayOfMonth, 
        OccupancyID, 
        CustomerVoice_RepairsSatisfactionFeedbackID,
        RowNumber, LAG(CustomerVoice_RepairsSatisfactionFeedbackID) OVER(PARTITION BY OccupancyID ORDER BY FirstDayOfMonth) AS Lag_Value,
        ROW_NUMBER() OVER(PARTITION BY OccupancyID ORDER BY FirstDayOfMonth) AS RN,
        CASE WHEN CustomerVoice_RepairsSatisfactionFeedbackID IS NOT NULL THEN 1 ELSE 0 END AS Flag            
    FROM 
        #temp2)SELECT 
    OccupancyID, 
    FirstDayOfMonth, 
    CustomerVoice_RepairsSatisfactionFeedbackID,
    CASE 
        WHEN Lag_Value IS NULL THEN PreviousCustomerVoice_RepairsSatisfactionFeedbackID
        ELSE Lag_Value 
    END AS PreviousNonNULLCustomerVoice_RepairsSatisfactionFeedbackID
FROM 
(
    SELECT *,
    (
        SELECT 
            TOP(1) CustomerVoice_RepairsSatisfactionFeedbackID 
        FROM 
            CTE k
        WHERE 
            k.Flag = 1 AND 
            k.RN < a.RN AND 
            k.OccupancyID = a.OccupancyID
        ORDER BY RN DESC
    ) AS PreviousCustomerVoice_RepairsSatisfactionFeedbackID
    FROM CTE 
a) b

我刚刚添加了按 RN 列排序以获取最高的 RN 值(以防相关子查询中存在超过 2 个值)。

© www.soinside.com 2019 - 2024. All rights reserved.