查询结果未按预期返回

Posted

技术标签:

【中文标题】查询结果未按预期返回【英文标题】:Query Result Not Returned As Expected 【发布时间】:2020-03-28 19:23:47 【问题描述】:

我正在努力解决几天前根据一位 SO 用户的建议尝试的查询,并使其与以下内容一起使用:

WITH your_table(ID,STOREDATE,VALUE,INFO)
AS
(
SELECT 1122,'1/1/2020',2,'DONE' UNION ALL
SELECT 1122,'1/2/2020',1,'DONE' UNION ALL
SELECT 1122,'1/3/2020',7,'DONE' UNION ALL
SELECT 1122,'1/4/2020',8,'DONE'
),

CTE AS
(
    SELECT ID,
    STOREDATE,
    VALUE,
    CASE 
        WHEN VALUE = 8 THEN 0
        WHEN VALUE + LAG(VALUE) OVER(ORDER BY STOREDATE) = 8 THEN 0
        WHEN VALUE + LEAD(VALUE) OVER(ORDER BY STOREDATE) = 8 THEN 0
        ELSE VALUE
    END VALUE2,
    INFO
    FROM your_table
)

SELECT *,
CASE 
    WHEN 
        (
            SELECT COUNT(*) FROM CTE A 
            WHERE A.VALUE2 = 0 AND A.STOREDATE < B.STOREDATE
        ) >= 1 AND B.VALUE = 8 THEN B.VALUE
    ELSE B.VALUE2
END VALUE3
FROM CTE B

注意:我的想法是在任何给定的行中求和 8。所以对于上面的输入,我预期的输出是这样的。

输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    0           //1 + 7 = 8; it'll update both the rows with zero
1122    1/3/2020    0           //For this, it's just fine
1122    1/4/2020    8       DONE

现在我的问题在于以下输入,我无法弄清楚如何获得预期的结果集。

输入

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    1       DONE
1122    1/3/2020    2       DONE
1122    1/4/2020    7       DONE

预期输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    0       
1122    1/3/2020    2       DONE
1122    1/4/2020    0       

输入

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    2       DONE
1122    1/3/2020    2       DONE
1122    1/4/2020    2       DONE

预期输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    0       
1122    1/2/2020    0       
1122    1/3/2020    0       
1122    1/4/2020    0       

我可能有几个 id 来获得如下的确切结果,但是对查询进行调整并不能达到我想要的结果。任何建议将不胜感激 - 谢谢。

WITH your_table(ID,STOREDATE,VALUE,INFO)
AS
(
SELECT 1122,'1/1/2020',2,'DONE' UNION ALL
SELECT 1122,'1/2/2020',7,'DONE' UNION ALL
SELECT 1122,'1/3/2020',1,'DONE' UNION ALL
SELECT 1122,'1/4/2020',8,'DONE' UNION ALL
SELECT 4466,'1/1/2020',2,'DONE' UNION ALL
SELECT 4466,'1/2/2020',7,'DONE' UNION ALL
SELECT 4466,'1/3/2020',1,'DONE' UNION ALL
SELECT 4466,'1/4/2020',8,'DONE'
),

CTE AS
(
    SELECT ID,
    STOREDATE,
    VALUE,
    CASE 
        WHEN VALUE = 8 THEN 0
        WHEN VALUE + LAG(VALUE) OVER(ORDER BY STOREDATE) = 8 THEN 0
        WHEN VALUE + LEAD(VALUE) OVER(ORDER BY STOREDATE) = 8 THEN 0
        ELSE VALUE
    END VALUE2,
    INFO
    FROM your_table
)

SELECT *,
CASE 
    WHEN 
        (
            SELECT COUNT(*) FROM CTE A 
            WHERE A.VALUE2 = 0 AND A.STOREDATE < B.STOREDATE
        ) >= 1 AND B.VALUE = 8 THEN B.VALUE
    ELSE B.VALUE2
END VALUE3
FROM CTE B

预期输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    0           
1122    1/3/2020    0           
1122    1/4/2020    8       DONE
4466    1/1/2020    2       DONE
4466    1/2/2020    0           
4466    1/3/2020    0           
4466    1/4/2020    8       DONE

更新 1:请检查以下内容

输入

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    1       DONE
1122    1/3/2020    2       DONE
1122    1/4/2020    7       DONE

预期输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    0       
1122    1/3/2020    2       DONE
1122    1/4/2020    0       

输入

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    2       DONE
1122    1/2/2020    2       DONE
1122    1/3/2020    2       DONE
1122    1/4/2020    2       DONE

预期输出

ID      STOREDATE   VALUE   INFO
1122    1/1/2020    0       
1122    1/2/2020    0       
1122    1/3/2020    0       
1122    1/4/2020    0   

【问题讨论】:

【参考方案1】:

您的第一个大错误是“stordate”不是日期,而是日期的字符串表示形式。因此,所有比较都将是字符串的比较,而不是日期的比较。作为字符串,首先出现的是“01/02/2020”或“02/01/2019”。

WITH your_table(ID,STOREDATE,VALUE,INFO)
AS
(
SELECT 1122,to_date('01/01/2020','dd/mm/yyyy'),2,'DONE' UNION ALL
SELECT 1122,to_date('01/02/2020','dd/mm/yyyy'),1,'DONE' UNION ALL
SELECT 1122,to_date('01/03/2020','dd/mm/yyyy'),7,'DONE' UNION ALL
SELECT 1122,to_date('01/04/2020','dd/mm/yyyy'),8,'DONE'
),

【讨论】:

AFAIK,TO_DATE 是 oracle 的内置函数,上面的示例用于 SQL Server @EdStevens。 @user8512043。该线程被标记为 oracle 和 sqlserver。这本身就是 OP 的一个错误,因为众所周知,解决方案很少是“数据库不可知论者”。开始问题中的第一个代码示例对我来说就像 oracle sql。无论如何,基本原则仍然成立——它将字符串视为日期,因此,比较不会按预期进行。【参考方案2】:

你能检查一下下面的解决方案吗-

DEMO HERE

DEMO2 HERE

WITH your_table(ID,STOREDATE,VALUE,INFO)
AS
(
SELECT 1122,'1/1/2020',2,'DONE' UNION ALL
SELECT 1122,'1/2/2020',7,'DONE' UNION ALL -- This two returns zero
SELECT 1122,'1/3/2020',1,'DONE' UNION ALL -- As 1 and 7 have sum of 8; it should check once I mean the sum 
SELECT 1122,'1/4/2020',7,'DONE' UNION ALL -- Unfortunately this returns zero as well
SELECT 4466,'1/1/2020',2,'DONE' UNION ALL
SELECT 4466,'1/2/2020',7,'DONE' UNION ALL
SELECT 4466,'1/3/2020',1,'DONE' UNION ALL
SELECT 4466,'1/4/2020',8,'DONE'
),

CTE AS
(
    SELECT ID,
    STOREDATE,
    VALUE,
    CASE 
        WHEN VALUE = 8 THEN 0
        WHEN VALUE + LAG(VALUE) OVER(ORDER BY ID, STOREDATE) = 8 
            AND ID = LAG(ID) OVER(ORDER BY ID, STOREDATE) THEN 0
        WHEN VALUE + LEAD(VALUE) OVER(ORDER BY ID, STOREDATE) = 8 
            AND ID = LEAD(ID) OVER(ORDER BY ID, STOREDATE) THEN 0
        ELSE VALUE
    END VALUE2,
    INFO
    FROM your_table
)

SELECT *,
CASE 
    WHEN 
        (
            SELECT COUNT(*) FROM CTE A 
            WHERE A.VALUE2 = 0 AND A.STOREDATE < B.STOREDATE
            AND A.ID = B.ID
        ) >= 1 AND B.VALUE = 8 THEN B.VALUE

    WHEN
        (
            SELECT SUM(A.VALUE) 
            FROM CTE A 
            WHERE A.VALUE2 = 0 
            AND A.STOREDATE < B.STOREDATE
            AND A.ID = B.ID
        )>= 8  THEN B.VALUE

    ELSE B.VALUE2
END VALUE3
FROM CTE B

【讨论】:

以上适用于多个 id @mkRabbani。但是没有返回预期的输出,请参阅我的输入示例 - 再次感谢。检查我在此处修改的输入样本 - dbfiddle.uk/… 好的,我会检查的。 @user8512043 请查看我更新的答案并参考链接 DEMO2 已经检查并工作了@mkRabbani。虽然最后两种类型不匹配。如果可以,请使用 Update 1 示例查看我更新的帖子。再次感谢您的时间和精力。 不确定您要指示哪个样本数据集:(

以上是关于查询结果未按预期返回的主要内容,如果未能解决你的问题,请参考以下文章

查询未按预期执行,无论如何都返回 -1

SQL NOT EXISTS 子查询未按预期运行

Lumen MySQL 查询未按预期处理 UTF8 值

MySQL NOT IN 子查询未按预期工作

如何找出 SQL 查询未按预期生成行的原因? [复制]

javax.persistence NamedQuery 未按预期工作