我试图创建一个依赖于 LEFT JOIN
条件,但我不确定是否可能,特别是在雪花。
我有三张table: ITEM
, ITEMHIERARCHY
,和 ITEMVALUE
```
CREATE TABLE ITEM
(
NAME STRING
);
INSERT INTO ITEM(NAME)
VALUES
('Item1'),('Item2'),('Item3'),('Item4'),('Item5'),('Item6');
CREATE TABLE ITEMHIERARCHY
(
ITEM STRING,
SUBITEM STRING
);
INSERT INTO ITEMHIERARCHY(ITEM,SUBITEM)
VALUES
('Item2','Item3'),('Item2','Item4'),('Item4','Item5'),('Item6','Item4');
CREATE TABLE ITEMVALUE
(
ITEM STRING,
VALUE NUMERIC(25,10)
);
INSERT INTO ITEMVALUE(ITEM,VALUE)
VALUES
('Item1',34.2),('Item3',40.5),('Item5',20.3),('Item6',77.7);
我的目标是返回所有 `ITEMs` 值和子项值汇总后:
Item1, 34.2
Item2, 60.8 //roll-up of Item3 + Item4
Item3, 40.5
Item4, 20.3 //roll-up of Item5
Item5, 20.3
Item6, 77.7 //since Item6 value is given, dont roll-up from Item4
注意,尽管 `Item6` 是从 `Item4` 因为已经有一个给定的 `77.7` 上 `ITEMVALUE` 表,则忽略汇总。
下面是我尝试的一个失败的递归查询,原因是 `LEFT JOIN` 在 `UNION ALL` 条款:
WITH RECURSIVE ITEMHIERARCHYFULL
-- Column names for the "view"/CTE
(ITEM,SUBITEM,VALUE)
AS
-- Common Table Expression
(
-- Anchor Clause
SELECT it.NAME ITEM, ih.SUBITEM, iv.VALUE
FROM ITEM it
--These left-joins work
LEFT JOIN ITEMVALUE iv ON iv.ITEM = it.NAME
LEFT JOIN ITEMHIERARCHY ih ON ih.ITEM = it.ITEM
AND iv.VALUE IS NULL
UNION ALL
-- Recursive Clause
SELECT ihf.ITEM, ih.SUBITEM,
IFF(ihf.VALUE IS NOT NULL,ihf.VALUE,iv.VALUE)
FROM ITEMHIERARCHYFULL ihf
LEFT JOIN ITEMVALUE iv ON iv.ITEM = ihf.SUBITEM
LEFT JOIN ITEMHIERARCHY ih ON ih.ITEM = ihf.SUBITEM
AND iv.VALUE IS NULL
)
-- This is the "main select".
SELECT ITEM, SUM(VALUE) AS VALUE
FROM ITEMHIERARCHYFULL
GROUP BY ITEM
ORDER BY ITEM
;
查询的目标是首先获取所有顶层 `ITEMs` 从 `ITEM` 表中,在 `ITEMVALUE` 表,如果找不到,则连接到 `ITEMHIERARCHY` 表以检索所有 `SUBITEMs` 构成了最高层 `ITEMs` . 然后我想递归地搜索 `ITEMVALUE` a的table `SUBITEM-VALUE` 匹配,或者,如果找不到,则检索 `SUBITEMs` 从 `ITEMHIERARCHY` table。
第一套 `LEFT-JOINs` 工作,但不是地下的 `UNION ALL` 告诉我错误:
SQL compilation error: OUTER JOINs with a self reference are not allowed in a recursive CTE.
有没有更好的方法来做我想做的事 `Snowflake` 还是我想的不对?
目前,我手动编写了递归层到5个级别,这意味着如果 `ITEMHIERARCHY` 表格变得更加复杂。
2条答案
按热度按时间v440hwme1#
下面是一个工作示例,它给出了您所期望的结果。您也可以在sqlfiddle上查看它。
结果:
jm81lzqq2#
下面是一个堆栈溢出问题,关于为什么
LEFT JOINs
在递归查询中是不允许的:链接,基本上是防止的∞ recursion
,这在我看来是一个有点弱的原因。在第二个响应中还建议,如果您的sql方言支持OUTER APPLY
你可以用它来代替函数等价,但是snowflake没有这个函数。下面是我的手动“递归”解决方案,最多可用于3个层次:
这显然是一种在语法上非常低效的方法,在每一步中,你都必须检查两者
ITEM
以及SUBITEM
值,然后重复NULL
检查以前的每一次ITEMVALUE
或者SUBITEMVALUE
table。我放进了SUBITEMs
对于每个级别,如果只运行查询的内部部分,则可以看到扩展是如何工作的。我还不得不使用CASE
语句来让事情在sqlfiddle上运行,但我更愿意使用IFF
以及IFNULL(Value1,IFNULL(Value2,Value3))
.以下是sql fiddle:link的工作代码和输出: