如何在同一个 table 上使用 apply 2 次?
How do I use apply 2 times on the same table?
这只是一个易于重现的例子。
正如 gslamed 所建议的那样,有一种解决方案可以避免使用两次应用。但这不是我需要的。我需要使用两次申请。
在这个例子中,我想取集合的第一个元素 (t.b)
在 v.c
WITH
s (a, b)
AS
(SELECT 1, 'ff' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 2, 'ee' FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
SELECT *
FROM v;
它正在工作。
然后我在数v.c
中有多少个元素
WITH
s (a, b)
AS
(SELECT 1, 'ff' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 2, 'ee' FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT count(*) c
FROM TABLE (t.b) x
) tb)
select * from v
现在我想要第一个元素以及 v.c 和 v.d
中有多少个元素
WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE,count(*) c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
select * from v
ORA-00937: not a single-group group function
睡不着,这很正常。我没有使用分组依据 .
因此我想用 v.
中的第二个子选择来计算
我试过两次加t外申请。但它不起作用
WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c,d)
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
OUTER APPLY (SELECT count(*) d
FROM TABLE (t.b) x
) tb2)
select * from v
ORA-00928: missing SELECT keyword
如何使用2次外部应用?
使用这个:
WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE,count(*) over() c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
select * from v
你只是多了一个右括号;当你有这个:
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
--------------------------------------------------------^
... 我标记的 )
结束了 with
子句。但是当你把它改成这样时:
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
--------------------------------------------------------^
OUTER APPLY (SELECT count(*) d
FROM TABLE (t.b) x
) tb2)
-----------------------------------^
.. 您保留了结束 CTE 的右括号,因此第二个 outer apply
不在有效位置。只需删除第一个标记为 )
并保留第二个标记为 )
.
对于复杂的查询,我倾向于缩进括号以使此类更加明显 - 所以第一个看起来不错:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
)
但是第二个没有:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
)
OUTER APPLY (
SELECT count(*) d
FROM TABLE (t.b) x
) tb2
)
更明显的应该是:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
OUTER APPLY (
SELECT count(*) d
FROM TABLE (t.b) x
) tb2
)
这只是一个易于重现的例子。 正如 gslamed 所建议的那样,有一种解决方案可以避免使用两次应用。但这不是我需要的。我需要使用两次申请。
在这个例子中,我想取集合的第一个元素 (t.b) 在 v.c
WITH
s (a, b)
AS
(SELECT 1, 'ff' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 2, 'ee' FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
SELECT *
FROM v;
它正在工作。
然后我在数v.c
中有多少个元素WITH
s (a, b)
AS
(SELECT 1, 'ff' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 1, 'ee' FROM DUAL
UNION ALL
SELECT 2, 'ee' FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT count(*) c
FROM TABLE (t.b) x
) tb)
select * from v
现在我想要第一个元素以及 v.c 和 v.d
中有多少个元素WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE,count(*) c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
select * from v
ORA-00937: not a single-group group function
睡不着,这很正常。我没有使用分组依据 .
因此我想用 v.
中的第二个子选择来计算我试过两次加t外申请。但它不起作用
WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c,d)
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
OUTER APPLY (SELECT count(*) d
FROM TABLE (t.b) x
) tb2)
select * from v
ORA-00928: missing SELECT keyword
如何使用2次外部应用?
使用这个:
WITH
s (a, b)
AS
(SELECT 1, TO_CLOB ('ff') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 1, TO_CLOB ('ee') FROM DUAL
UNION ALL
SELECT 2, TO_CLOB ('ee') FROM DUAL),
t (a, b)
AS
( SELECT s.a, COLLECT (s.b)
FROM s
GROUP BY s.a),
v (a, b, c)
AS
(SELECT t.a, t.b, tb.c
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE,count(*) over() c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
select * from v
你只是多了一个右括号;当你有这个:
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
--------------------------------------------------------^
... 我标记的 )
结束了 with
子句。但是当你把它改成这样时:
AS
(SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY) tb)
--------------------------------------------------------^
OUTER APPLY (SELECT count(*) d
FROM TABLE (t.b) x
) tb2)
-----------------------------------^
.. 您保留了结束 CTE 的右括号,因此第二个 outer apply
不在有效位置。只需删除第一个标记为 )
并保留第二个标记为 )
.
对于复杂的查询,我倾向于缩进括号以使此类更加明显 - 所以第一个看起来不错:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
)
但是第二个没有:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
)
OUTER APPLY (
SELECT count(*) d
FROM TABLE (t.b) x
) tb2
)
更明显的应该是:
AS
(
SELECT t.a, t.b, tb.c,tb2.d
FROM t
OUTER APPLY (
SELECT x.COLUMN_VALUE c
FROM TABLE (t.b) x
FETCH FIRST 1 ROW ONLY
) tb
OUTER APPLY (
SELECT count(*) d
FROM TABLE (t.b) x
) tb2
)