这是一个错误,还是 Snowflake 不完全支持 WHERE EXISTS 子句中的相关子查询?

问题描述

如果过滤条件依赖于合并来自外部表和子查询表的列,则 SNowflake 会为 EXISTS 子句抛出错误。如果我从 COALESCE 中删除外部表列或用长格式等效逻辑替换 COALESCE,则查询将运行。

我看到了这个错误,特别是sql 编译错误:无法评估不受支持的子查询类型,因为我认为这是一个相当简单的 WHERE EXISTS 子句。这适用于我使用过的每个(最近的)sql 变体(例如 sql Server、Postgres),所以我有点担心 SNowflake 不支持它。我错过了什么吗?

我在 2019 年发现了似乎是 similar question at Snowflake's Community内容,其中当 EXISTS 子句包含 WHERE 过滤条件时,SNowflake 失败了,该条件从外部查询中引用了一个列,而不是加入表。那里没有明确的解决方案。

SNowflake 的 documentation on its limited support for subqueries 表示它支持“WHERE 子句中的 EXISTS、ANY/ALL 和 IN 子查询”的相关和不相关子查询

那么为什么它在这个 EXISTS 子句上失败了呢?我看到的是错误,还是没有明确记录的雪花限制?

重现问题的代码

CREATE OR REPLACE TEMPORARY TABLE Employee (
   Emp_SK INT NOT NULL
);

CREATE OR REPLACE TEMPORARY TABLE Employee_X_Pay_Rate (
   Emp_SK INT NOT NULL,Pay_Rate_SK INT NOT NULL,Start_Date TIMESTAMP_NTZ NOT NULL,End_Date TIMESTAMP_NTZ NOT NULL
);

CREATE OR REPLACE TEMPORARY TABLE Employee_X_Location (
   Emp_SK INT NOT NULL,Location_SK INT NOT NULL,End_Date TIMESTAMP_NTZ NULL
);
INSERT INTO Employee
VALUES (1);

INSERT INTO Employee_X_Pay_Rate 
VALUES 
    (1,1,'2018-01-01','2019-03-31'),(1,2,'2019-04-01','2021-03-31'),3,'2021-04-01','2099-12-31')
;

INSERT INTO Employee_X_Location
VALUES
    (1,101,'2019-12-31'),102,'2020-01-01','2020-12-31'),103,'2021-01-01',NULL)
;
SET Asof_Date = TO_DATE('2021-05-31','yyyy-mm-dd'); -- changing this to TO_TIMESTAMP makes no difference
SELECT 
   emp.Emp_SK,empPay.Pay_Rate_SK,$Asof_Date AS Report_Date,empPay.Start_Date AS Pay_Start_Date,empPay.End_Date AS Pay_End_Date
FROM Employee emp
   INNER JOIN Employee_X_Pay_Rate empPay
      ON emp.Emp_SK = empPay.Emp_SK
      AND $Asof_Date BETWEEN empPay.Start_Date AND empPay.End_Date
WHERE EXISTS (
   SELECT 1 FROM Employee_X_Location empLoc
   WHERE emp.Emp_SK = empLoc.Emp_SK
      -- Issue: Next line fails. empLoc.End_Date can be null
      AND $Asof_Date BETWEEN empLoc.Start_Date AND COALESCE(empLoc.End_Date,empPay.End_Date)
);

如果我用以下任一内容替换问题行,查询就会运行。

-- Workaround 1
AND (
   $Asof_Date >= empLoc.Start_Date
   AND ($Asof_Date <= empLoc.End_Date OR (empLoc.End_Date IS NULL AND $Asof_Date <= empPay.End_Date))
)

-- Workaround 2
AND $Asof_Date BETWEEN empLoc.Start_Date AND COALESCE(empLoc.End_Date,CURRENT_DATE)

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...