Snowflake (LEFT JOIN) LATERAL:无法评估不支持的子查询类型

2023-11-25

横向连接

在 FROM 子句中,LATERAL 关键字允许内联视图引用该内联视图之前的表表达式中的列。

横向连接的行为更像是相关子查询,而不是大多数连接。

让我们稍微调整一下文档中提供的代码:

CREATE TABLE departments (department_id INTEGER, name VARCHAR);
CREATE TABLE employees (employee_ID INTEGER, last_name VARCHAR,
                        department_ID INTEGER, project_names ARRAY);

INSERT INTO departments (department_ID, name) VALUES 
    (1, 'Engineering'), 
    (2, 'Support'),
    (3, 'HR');  -- adding new row

INSERT INTO employees (employee_ID, last_name, department_ID) VALUES 
    (101, 'Richards', 1),
    (102, 'Paulson',  1),
    (103, 'Johnson',  2);  

Query:

SELECT * 
FROM departments AS d,
LATERAL (SELECT * FROM employees AS e 
         WHERE e.department_ID = d.department_ID 
         ORDER BY employee_id DESC LIMIT 1) AS iv2  -- adding ORDER BY ... LIMIT ...
ORDER BY employee_ID;

SQL编译错误:无法计算不支持的子查询类型

是的,我知道我可以重写这个查询ROW_NUMBER()或其他方式。


1)为什么使用TOP/LIMIT在这种特殊情况下不可能吗?

2)有没有语法可以实现LEFT JOIN LATERAL/OUTER APPLY?

我也希望能够获取结果集中的所有源行,即使 LATERAL 子查询没有为它们生成任何行。得到最终结果:

┌────────────────┬──────────────┬──────────────┬────────────┬────────────────┬───────────────┐
│ department_id  │    name      │ employee_id  │ last_name  │ department_id  │ project_names │
├────────────────┼──────────────┼──────────────┼────────────┼────────────────┼───────────────┤
│             1  │ Engineering  │ 102          │ Paulson    │ 1              │ null          │
│             2  │ Support      │ 103          │ Johnson    │ 2              │ null          │
│             3  │ HR           │ null         │ null       │ null           │ null          │
└────────────────┴──────────────┴──────────────┴────────────┴────────────────┴───────────────┘

db小提琴演示


因此,尽管我们之前讨论过您知道可以重写它,但这里是重写

WITH departments AS (
    SELECT * FROM VALUES
        (1, 'Engineering'), 
        (2, 'Support'),
        (3, 'HR')
        v(department_ID, name)
), employees AS (
    SELECT * FROM VALUES 
        (101, 'Richards', 1),
        (102, 'Paulson',  1),
        (103, 'Johnson',  2)
        v(employee_ID, last_name, department_ID)
), dep_emp AS (
  SELECT * 
  FROM employees 
  QUALIFY ROW_NUMBER() OVER (PARTITION BY department_ID ORDER BY employee_id) = 1
)
SELECT * 
FROM departments AS d
LEFT JOIN dep_emp AS e ON d.department_ID = e.department_ID
ORDER BY employee_ID;

如您所愿给出:

DEPARTMENT_ID    NAME           EMPLOYEE_ID    LAST_NAME    DEPARTMENT_ID
1                Engineering    101            Richards     1
2                Support        103            Johnson      2
3                HR             null           null         null

通过从 LATERAL 转移到带有 QUALIFY 的 CTE 来实现 LIMIT/TOP,然后使用 LEFT JOIN 获取空匹配,您就拥有了所需的步骤。

对于为什么会这样这个未提出的问题。 Snowflake 并不是真正的每行数据库,它更像是一个 Map/Reduce/MergeJoin 过程,并且它可以将简单的相关子查询重写为多步骤(也称为 CTE/joins),但它不能重写复杂的东西。他们一直在改进它。但是,如果您了解数据并且了解模型,那么以批量操作来表达事物并让 MergeJoin 的强大功能为您带来胜利是最有意义的。

有没有语法来实现LEFT JOIN LATERAL/OUTER APPLY? 这是通过参数完成的, OUTER => TRUE in the FLATTEN command

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Snowflake (LEFT JOIN) LATERAL:无法评估不支持的子查询类型 的相关文章

随机推荐