可以将这种联接设置为通用CTE吗?

时间:2019-05-30 14:07:29

标签: sql common-table-expression

快速序言:我想说这是针对oracle数据库运行的,以防影响答案,但是CTE对于我使用的其他RDBMS(SQL Server,DB2)是通用的,所以我希望可以能够在其中使用。

LEFT JOIN  
    (SELECT * 
     FROM 
         (SELECT 
              HH.*, 
              ROW_NUMBER() OVER (PARTITION BY HH.WORKSHEET_HISTORY_ID
                                 ORDER BY QQ.GOBLIN_HOBBIT_ID DESC) AS "INDICATOR"
          FROM 
              ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
          INNER JOIN 
              ILU.GOBLIN_HOBBIT QQ ON QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
          INNER JOIN 
              ILU.HOBBIT_master ZZ ON ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
          WHERE 
              ZZ.HOBBIT_CODE = '99'
              AND ZZ.ASSOCIATION_CODE <> 'GNDLF') Z
     WHERE 
         Z."INDICATOR" = 1) MITHRIL_HOBT ON MITHRIL_HOBT.WORKSHEET_HISTORY_ID = hst.WORKSHEET_HISTORY_ID

我想在这里完成的任务就是将这种联接变成CTE。我可以做到,但是我真正感兴趣的是能够在不同条件下从主查询中调用该CTE:

WHERE 
    ZZ.HOBBIT_CODE = '%PARAMETER1'
    AND ZZ.ASSOCIATION_CODE <> '%PARAMETER2'  

这可能是不可能的,这是一个有效的答案。但是要澄清一下,我知道我可以通过其他方式(创建函数)完成相同的事情,而且很好,我很好奇它是否可以作为CTE完成,因为CTE易于快速编写并清理即席查询进入更多可重用的,更少的临时查询。

(最后,快速描述一下联接已经以一种奇怪的方式进行了构造:因为我需要获得第一行,而且这是我唯一可以确定的方式,但不会破坏性能我什至在缺少索引的地方添加了索引,而我使用的另一种方法仍然在整个表中循环。

首先,引起该问题的尝试是这样的(这是在SELECT而不是子查询中):

case when (   SELECT 1 FROM 
        ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
        INNER JOIN ILU.GOBLIN_HOBBIT QQ
            on QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
        INNER join ILU.HOBBIT_master ZZ
            on ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
         WHERE ZZ.HOBBIT_CODE='99'
         AND ZZ.ASSOCIATION_CODE <> 'GNDLF'
         and rownum = 1
) is not null then 1 else 0 end as MITHRIL_INDICATOR

(ps代码有些模糊,我不花钱做事)

1 个答案:

答案 0 :(得分:1)

Oracle确实支持CTE,但是文档将其称为with子句:

with CTE1 as
(
select HH.*, row_number() 
               over (
                 partition by HH.WORKSHEET_HISTORY_ID
                 order by QQ.GOBLIN_HOBBIT_ID desc
                    ) as "INDICATOR"
FROM ILU.WORKSHEET_HOBBIT_RECOMMENDATIONS HH
INNER JOIN ILU.GOBLIN_HOBBIT QQ
  on QQ.GOBLIN_HOBBIT_id = HH.GOBLIN_HOBBIT_id
INNER join ILU.HOBBIT_master ZZ
  on ZZ.HOBBIT_master_id = QQ.HOBBIT_master_id
WHERE ZZ.HOBBIT_CODE='99'
AND ZZ.ASSOCIATION_CODE <> 'GNDLF' 
)
, CTE2 as 
(
select * 
from CTE1
where INDICATOR = 1
)

select somestuff
from somewhere hst
LEFT join CTE2 
  on CTE2.Worksheet_history_id = hst.WORKSHEET_HISTORY_ID