将select转换为子查询时缺少行

时间:2017-02-08 09:29:46

标签: sql oracle

我对这些结果感到惊讶。在子查询中包装查询时,group by子句会突然删除具有特定值的所有行。

有谁可以帮我弄清楚会发生什么?

简而言之,这是我的问题,我不明白最后的结果:

with my_cte as (
 select complex stuff from tables
)

select checktype from my_cte group by checktype

返回2行:PRE,POST。

with my_cte as (
 select complex stuff from tables
)

select distinct checktype from my_cte

这也会返回2行:PRE,POST。

with my_cte as (
 select complex stuff from tables
)

select * from (
  select distinct checktype from my_cte
)

这也会返回2行:PRE,POST

with my_cte as (
 select complex stuff from tables
)

select * from (
  select checktype from my_cte group by checktype
)

这只返回1行! PRE。为什么呢?

如果我使用另一个CTE而不是子查询,也会发生同样的事情。

为什么oracle中的子查询会突然丢弃某个值的所有行?

Oracle版本:
Oracle Database 12c企业版12.1.0.2.0版 - 64位生产

1 个答案:

答案 0 :(得分:1)

在挖掘之后我发现在我的CTE中我使用了一个TABLE函数和一个UNION ALL,这似乎是麻烦的原因:

WITX X AS (
     SELECT DISTINCT
       T.TS,
       TRIM(REGEXP_SUBSTR(TREPSUMMARY, '.+', 1, LEVELS.COLUMN_VALUE)) AS MISSING,
       DATE
     FROM 
       BASE_POST_EXCEPTIONS T,
       TABLE(CAST(MULTISET(SELECT LEVEL FROM DUAL CONNECT    BY  LEVEL <= LENGTH (REGEXP_REPLACE(   T.CMPLEXTREPSUMMARY, '.+'))  + 1) AS ODCINUMBERLIST)) LEVELS
     WHERE REGEXP_SUBSTR(T.CMPLEXTREPSUMMARY, '.+', 1,    LEVELS.COLUMN_VALUE) LIKE 'my query'
)

Y AS (
  SELECT TS, MISSING, DATE FROM G
),

MY_UNION AS (
  SELECT * FROM X /* CAUSED TROUBLE SOMEHOW */
  UNOIN ALL
  SELECT * FROM Y
)

为了解决这个问题,我必须提示查询计划程序在UNION ALL之前对表进行materilize

MY_UNION AS (
  SELECT /*+ materialize */ * FROM X
  UNOIN ALL
  SELECT /*+ materialize */ * FROM Y
)

不知道为什么会这样。将尝试逆向工程并创建一个简单的可重现的测试用例。