【发布时间】:2019-01-30 13:23:18
【问题描述】:
我一天中的大部分时间都在研究这个问题,但到目前为止还没有找到正确的答案。我正在尝试找到一种在自定义函数中返回 SQL 查询结果的方法。我们系统中的所有数据都是交易和生效日期,我们通常被要求比较两个时间点之间的数据。现在我使用 WITH 子句来提取两个不同的数据集(“之前”和“之后”)。问题是用于创建这些数据集的查询非常长,并且每个 CTE 基本上是相同的东西,只是具有不同的生效日期。我想找到一种方法来创建一个函数,我可以将有效/交易日期传递给进行比较,这样我的 SQL 中就没有太多冗余逻辑了。这是一个问题 - 我具有只读访问权限,无法在数据库中创建任何对象。我已经读到我可以使用 Declare 语句来解决这个问题,但到目前为止还无法做到这一点。
这是我现在拥有的一个示例。我已经大大简化了查询,所以这不是一团糟。
WITH effective_date AS (
SELECT to_date(:EFFDT) AS effdt,
to_date(:REPORT_DATE_BEFORE) AS report_dt_before,
to_date(:REPORT_DATE_AFTER) AS report_dt_after
FROM dual),
election_data_before AS (
SELECT *
FROM effective_date efd
CROSS JOIN elections e
WHERE efd.effdt >= e.start_dt
AND efd.effdt < e.until_dt
AND efd.report_dt_before >= e.tran_start_dt
AND efd.report_dt_before < e.tran_until_dt),
election_data_after AS (
SELECT *
FROM effective_date efd
CROSS JOIN elections e
WHERE efd.effdt >= e.start_dt
AND efd.effdt < e.until_dt
AND efd.report_dt_after >= e.tran_start_dt
AND efd.report_dt_after < e.tran_until_dt)
SELECT ...
FROM election_data_before edb
INNER JOIN election_data_after eda
ON edb.employee_id = eda.employee_id
AND edb.benefit_type = eda.benefit_type
WHERE ...
这看起来还不错,但就像我说的那样,这非常简化。这就是我想做的事情。我知道这是垃圾代码,只是想说明我所描绘的。
FUNCTION elections ( effdt date, report_dt date )
RETURN (
SELECT *
FROM elections e
WHERE effdt >= e.start_dt
AND effdt < e.until_dt
AND report_dt >= e.tran_start_dt
AND report_dt < e.tran_until_dt)
SELECT ...
FROM elections(:EFFDT, :REPORT_DT_BEFORE) edb
ON pp.employee_id = edb.employee_id
INNER JOIN elections(:EFFDT, :REPORT_DT_AFTER) eda
ON pp.employee_id = eda.employee_id
AND edb.benefit_type = eda.benefit_type
WHERE ...
我整天都在阅读有关流水线函数和匿名块的信息,但无法将它们全部放在一起。如果有人能指出我正确的方向,或者让我知道我是否最好只使用两种不同的 CTE,我将不胜感激。谢谢!
【问题讨论】: