使用我指定的日期列创建查询,但无法创建临时表
Posted
技术标签:
【中文标题】使用我指定的日期列创建查询,但无法创建临时表【英文标题】:Creating a query with a column of dates that I specify without the ability to create a temporary table 【发布时间】:2021-08-03 14:37:38 【问题描述】:我在我的数据库中具有只读访问权限,并且我有一个如下所示的表;
我想要一个如下所示的输出
这可能吗?我想我需要一张日期表才能通过,但我不知道该怎么做。任何帮助将不胜感激。
【问题讨论】:
请不要嵌入数据图像。而是使用问题编辑器中可用的格式将数据作为文本放置。 使用 oracle 函数打破日期并按部分插入新表中。搜索insert-select
***.com/questions/7323407/…
@MatBailie - 我的错,我会更加小心。
你想要的输出不清楚,为什么你有一个额外的行?为什么不是 7-2018 年?尝试更好地解释你的逻辑
我想要的输出将包括从 1/2012 开始的每个月和每个年。我只添加了一些作为示例。应该更具描述性。我的问题是,我正在查看的表格没有该范围的日期,所以我必须以某种方式创建它们。
【参考方案1】:
使用子查询分解子句 (WITH
) 生成要加入的日期:
WITH dates ( dt ) AS (
SELECT DATE '2016-07-01' FROM DUAL UNION ALL
SELECT DATE '2017-07-01' FROM DUAL UNION ALL
SELECT DATE '2019-08-01' FROM DUAL
)
SELECT EXTRACT(MONTH FROM d.dt) AS Month,
EXTRACT(YEAR FROM d.dt) AS Year,
NVL2(t.SomeValue, 'Y', 'N') AS "Change?"
FROM dates d
LEFT OUTER JOIN table_name t
ON ( TRUNC(t.effective_date, 'MM') = d.dt )
我想要的输出将包括从 2012 年 1 月开始的每个月和每年。
然后使用递归子查询分解子句:
WITH dates ( dt ) AS (
SELECT DATE '2012-01-01' FROM DUAL
UNION ALL
SELECT ADD_MONTHS( dt, 1 )
FROM dates
WHERE ADD_MONTHS( dt, 1 ) <= SYSDATE
)
SELECT EXTRACT(MONTH FROM d.dt) AS Month,
EXTRACT(YEAR FROM d.dt) AS Year,
NVL2(t.SomeValue, 'Y', 'N') AS "Change?"
FROM dates d
LEFT OUTER JOIN table_name t
ON ( TRUNC(t.effective_date, 'MM') = d.dt )
【讨论】:
我认为您还需要与 Lag(t.SomeValue) 进行比较,以查看是否有与上个月相同的记录。类似Case When t.SomeValue Is Null Then 'N' When t.SomeValue= nvl(lag(t.SomeValue,1) Over (Order By d.dt), t.SomeValue) Then 'N' Else 'Y' End
@ChrisMaurer 这实际上取决于 OP 如何定义“更改”。如果“更改”是源表中的新行(因为它们在图像中的值似乎相同并且它们正在显示更改)那么,不,我不需要使用LAG
;但是,如果他们想要不同的价值观,那么,是的,你会想要的。
我认为这可以为我解答。非常感谢!【参考方案2】:
您可以使用递归来打破记录到谁年份...
WITH
fragmented (
window_start,
window_close,
some_value,
interval_start,
interval_close
)
AS
(
SELECT
window_start,
window_close,
some_value,
interval_start,
CASE
WHEN add_months(interval_start, 12) < window_close
THEN add_months(interval_start, 12)
ELSE window_close
END
AS interval_close
FROM
(
SELECT
effective_date AS window_start,
LEAD(effective_date) OVER (ORDER BY effective_date) AS window_close,
some_value,
effective_date AS interval_start
FROM
example
)
lookahead
UNION ALL
SELECT
window_start,
window_close,
some_value,
add_months(interval_start, 12),
CASE
WHEN add_months(interval_start, 24) < window_close
THEN add_months(interval_start, 24)
ELSE window_close
END
FROM
fragmented
WHERE
interval_close < window_close
)
SELECT
*
FROM
fragmented
ORDER BY
window_start,
interval_start
;
演示:https://dbfiddle.uk/?rdbms=oracle_18&fiddle=ca1fef00069c178c28e09d209db35395
【讨论】:
以上是关于使用我指定的日期列创建查询,但无法创建临时表的主要内容,如果未能解决你的问题,请参考以下文章