快速序言:我想说这是针对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代码有些模糊,我不花钱做事)
答案 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