代码之家  ›  专栏  ›  技术社区  ›  AntoineB

redshift/mysql-检查两个整数列之间的不相等返回错误的结果

  •  0
  • AntoineB  · 技术社区  · 7 年前

    我正在redshift上查询一些结果,当我检查两个整数列之间是否不相等时,偶然发现了一个似乎是错误的地方,当一些结果中有一个列的值为空时。

    下面是一个简单的测试:

    WITH test AS (
        SELECT 1 AS orig, 1 AS dest UNION
        SELECT 1 AS orig, 2 AS dest UNION
        SELECT 1 AS orig, NULL AS dest
    )
    SELECT COUNT(*) FROM test WHERE orig != dest
    

    我显然希望结果是 2 ,但它可以打印 1 .

    这种行为的原因是什么?

    谢谢

    编辑:刚刚检查了mysql,我得到了相同的结果。

    3 回复  |  直到 7 年前
        1
  •  2
  •   nobody    7 年前

    空值被认为是一个未知值。 1 != null 结果被评估为false。

    因此,在您的情况下,结果是1 1 != 2

        2
  •  0
  •   AntoineB    7 年前

    正如vk_217所说,这是因为null不被视为一个值,不能与现有值进行比较,因此任何类型的比较都将返回null(因此,将与where子句不匹配)。

    您可以在本文中找到有关行为的更多详细信息: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/

    如果你需要有预期的行为,以下是我最终使用的:

    WITH test AS (
        SELECT 1 AS orig, 1 AS dest UNION
        SELECT 1 AS orig, 2 AS dest UNION
        SELECT 1 AS orig, NULL AS dest
    )
    SELECT COUNT(*) FROM test WHERE (
        (orig IS NULL AND dest IS NOT NULL)
        OR
        (orig IS NOT NULL AND dest IS NULL)
        OR
        (orig != dest)
    )
    
        3
  •  0
  •   Elle    7 年前

    mysql和redshift都提供了 COALESCE 可以在可能存在空值的地方使用的函数。此查询将为您提供预期的结果。

    -- 9999999 value used below is a value sure not to exist in other table.
    -- can be 0 or any value you choose based on your a prioiri knowledge of the data
    
    WITH test AS (
        SELECT 1 AS orig, 1 AS dest UNION
        SELECT 1 AS orig, 2 AS dest UNION
        SELECT 1 AS orig, NULL AS dest
    )
    SELECT COUNT(*) FROM test WHERE orig != COALESCE(dest,999999999)