【问题标题】:Snowflake SQL Query Left Join Issue雪花 SQL 查询左连接问题
【发布时间】:2020-11-05 17:27:18
【问题描述】:

对于我们的其中一个代码,左连接在 snowflake 中的行为不正确。如果您能找到相同的解决方案,请寻求您的帮助。

我们有一个示例数据设置,如下所述,使用 basicc 表连接。

CREATE TABLE patient_test(pid INT);
INSERT INTO patient_test (pid) VALUES (100);

CREATE TABLE pateint_entry_test (pid INT,DateAdded DATETIME);
INSERT INTO pateint_entry_test (pid, DateAdded) VALUES (100, '2020-07-13');

现在看下面的代码,我只是为您提供我们与其他查询集一起使用的示例子查询。我们的动机是根据给定的开始/结束日期为每位患者输入日期。


WITh patient_cte  AS(
          SELECT * FROM patient_test
      )
      ,
      dates AS(
       SELECT  DATEDIFF(day, CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-06') AS TIMESTAMP_NTZ)),
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-12') AS TIMESTAMP_NTZ))) AS Total_Days,
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-06') AS TIMESTAMP_NTZ)) AS Start_Date,
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-12') AS TIMESTAMP_NTZ)) AS end_date
      )
      ,
      cte2 (date) as (
      SELECT TO_DATE(START_DATE) FROM dates
      UNION ALL
      SELECT TO_DATE(DATEADD(day, 1, date)) FROM cte2 WHERE date < (SELECT TOP 1 END_DATE FROM dates)
      ),
      cte3 AS (
          select * from patient_cte
              cross join cte2
      )

      SELECT cte3.pid as p_pid,
        pateint_entry_test.pid as p_entry_pid,
        pateint_entry_test.DateAdded,
        cte3."DATE" ,
        IFNULL( pateint_entry_test.DateAdded, cte3."DATE") AS CALCULATEDDATEMEASURED
     FROM cte3
        LEFT JOIN pateint_entry_test ON
            cte3.pid = pateint_entry_test.pid AND
            cte3."DATE" = TO_DATE(pateint_entry_test.DateAdded)

查询的输出结果如下。

您可以看到第 2 到第 7 行的 CALCULATEDDATEMEASURED2020-07-06 00:00:00。但是由于DAETADDED 即将为空,那么它应该根据DATE 列值来适当的日期(基于此条件IFNULL( pateint_entry_test.DateAdded, cte3."DATE")

期待下面的查询输出

不确定出了什么问题,但它的行为不符合预期。非常感谢您对此的帮助。谢谢。

【问题讨论】:

  • 这看起来像是一个错误,您应该向 Snowflake 报告。我很好奇你为什么使用非标准的IFNULL() 而不是标准的COALESCE()。但是,我怀疑这会对您的结果产生影响。
  • 感谢@GordonLinoff 恢复,之前尝试过coalesce(),但它的行为方式相同。
  • 这个语句应该有按日期排序吗? (SELECT TOP 1 END_DATE FROM dates) 这很难重现或帮助调试您在示例代码中引用的表的示例数据。
  • 感谢@MikeWalton 恢复,我在此处添加了一个工作示例查询,以便于调试。您也可以在雪花环境中运行相同的代码库。尝试按照您的建议添加订单,但没有帮助。
  • use text, not images/links, for text--including tables & ERDs。仅将图像用于无法表达为文本或增强文本的内容。在图片中包含图例/键和说明。

标签: sql left-join snowflake-cloud-data-platform isnull snowsql


【解决方案1】:

我不确定这是否是一个错误,但这是由于基于您编写查询的方式的类型强制。这是您的查询,在 IFNULL 语句中应用的 TO_DATE 逻辑与在联接中应用的逻辑相同(以及 COALESCE 以表明它产生与 IFNULL 相同的结果):

WITh patient_cte  AS(
          SELECT * FROM patient_test
      )
      ,
      dates AS(
       SELECT  DATEDIFF(day, CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-06') AS TIMESTAMP_NTZ)),
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-12') AS TIMESTAMP_NTZ))) AS Total_Days,
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-06') AS TIMESTAMP_NTZ)) AS Start_Date,
                            CONVERT_TIMEZONE('EST', 'UTC', CAST(TO_TIMESTAMP('2020-07-12') AS TIMESTAMP_NTZ)) AS end_date
      )
      ,
      cte2 (date) as (
      SELECT TO_DATE(START_DATE) FROM dates
      UNION ALL
      SELECT TO_DATE(DATEADD(day, 1, date)) FROM cte2 WHERE date < (SELECT TOP 1 END_DATE FROM dates)
      ),
      cte3 AS (
          select * from patient_cte 
              cross join cte2 
      )
      SELECT cte3.pid as p_pid,
        pateint_entry_test.pid as p_entry_pid,
        pateint_entry_test.DateAdded,
        cte3."DATE",
        IFNULL( pateint_entry_test.DateAdded, cte3."DATE") AS ORIGINAL_ERROR,
        IFNULL( to_date(pateint_entry_test.DateAdded), cte3."DATE") AS CALCULATEDDATEMEASURED,
        coalesce(to_date(pateint_entry_test.DateAdded), cte3."DATE") as from_coalesce
     FROM cte3 
        LEFT JOIN pateint_entry_test 
            ON cte3.pid = pateint_entry_test.pid 
            AND cte3."DATE" = to_date(pateint_entry_test.DateAdded);

在 Snowflake 中运行它会产生这样的结果:

【讨论】:

    猜你喜欢
    • 2014-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 1970-01-01
    • 2020-10-30
    • 2020-12-18
    相关资源
    最近更新 更多