为什么 COUNTS_BY_COLOUR.COUNTS 是 oracle apex 中的无效标识符

why the COUNTS_BY_COLOUR.COUNTS is invalid identifier in oracle apex

当我指定列的名称 (select counts_by_colour.colour,counts_by_colour.counts ) 时,以下代码会出错,但如果我说 select *,代码就会执行。为什么?

select counts_by_colour.colour,counts_by_colour.counts
from (select *
        from bricks
        CROSS JOIN (
        select count(*) as "total" from bricks) counts
        INNER JOIN (
         select colour, count(*) as "counts"
         from   bricks
         group by colour
       ) colours
       on bricks.colour=colours.colour) "counts_by_colour";

输出:

ORA-00904: "COUNTS_BY_COLOUR"."COUNTS": invalid identifier

您使用了带引号的标识符 "counts_by_colour" 并且带引号的标识符区分大小写。

相反,不带引号的标识符被隐式转换为 upper-case,因此 counts_by_colour 被转换为 COUNTS_BY_COLOUR

比较两者时,"counts_by_colour"COUNTS_BY_COLOUR 不是相同的标识符,因为它们的大小写不同,因此无法识别 COUNTS_BY_COLOUR

您稍后会发现相同的问题,因为您有引用的 "counts" 和未引用的 counts

解决方案(大部分)是从不使用带引号的标识符。


更根本的是,不需要使用 colours_by_counts 别名(并且可能在语法上无效),就像使用这么多嵌套括号一样,您可以参考 table 和 sub-query别名:

select colours.colour,
       colours.counts
from   bricks
       CROSS JOIN (select count(*) as total from bricks) counts
       INNER JOIN (
         select colour, count(*) as counts
         from   bricks
         group by colour
       ) colours
       on bricks.colour=colours.colour;

其中,对于示例数据:

CREATE TABLE bricks (id, colour) AS
SELECT 1, 'red' FROM DUAL UNION ALL
SELECT 2, 'red' FROM DUAL UNION ALL
SELECT 3, 'red' FROM DUAL UNION ALL
SELECT 4, 'green' FROM DUAL UNION ALL
SELECT 5, 'green' FROM DUAL UNION ALL
SELECT 6, 'blue' FROM DUAL;

输出:

COLOUR COUNTS
red 3
red 3
red 3
green 2
green 2
blue 1

如果您不想重复,则只需使用汇总的 sub-queries:

select *
from   (
         select colour, count(*) as counts
         from   bricks
         group by colour
       ) colours
       CROSS JOIN (select count(*) as total from bricks) counts;

或者,更简单地说,使用解析函数:

select colour,
       COUNT(*) AS counts,
       SUM(COUNT(*)) OVER () AS total
from   bricks
GROUP BY colour;

这两个输出:

COLOUR COUNTS TOTAL
red 3 6
green 2 6
blue 1 6

db<>fiddle here