我正在使用oraclesql,在使用交叉连接时遇到了一个问题。我有一个表,services,它有服务的开始和结束日期:
SRVC START END
Therapy JAN-1-20 JAN-5-20
Baseball FEB-15-20 FEB-18-20
我需要将此表转换为以下内容:
SRVC DATE
Therapy JAN-1-20
Therapy JAN-2-20
...
Therapy JAN-5-20
Baseball FEB-15-20
Baseball FEB-16-20
...
Baseball FEB-18-20
基本上,我需要每天一行,而不是一个日期范围。我目前的做法如下。我还有一张table,日期\时间,上面有日期,例如。
CALDR_DT
JAN-1-20
...
DEC-31-20
我正在做以下工作
SELECT s."SRVC", d."CALDR_DT"
FROM SERVICES s
CROSS JOIN DATE_TIME d
WHERE d."CALDR_DT" >= s."START" AND d."CALDR_DT" <= s."END";
我遇到的问题是,这运行速度非常慢,因为实际上,我有一个更大的数据集。有没有一个更有效的方法来做这件事,我错过了?
谢谢!
3条答案
按热度按时间4xrmg8kj1#
你不需要使用
DATE_TIME
表和aJOIN
; 相反,您可以使用递归子查询分解子句(recursive)WITH
子句)生成行:(作为旁白,不要使用
START
,END
以及DATE
因为它们是关键字,所以需要将它们括在双引号中,这使它们区分大小写,以便能够在查询中使用。)因此,对于您的示例数据:
这将输出:
db<>在这里摆弄
92dk7w1h2#
不确定这是否有帮助,但当你有两个
CROSS JOIN
和一个WHERE
子句中的条件使用两个表中的元素,您可以重写它以使用INNER JOIN
相反。。。有时数据库可以推断出更好的执行计划。同样,我无法预测这是否会对您的情况有所帮助,但当它确实有帮助时,改进通常集中在更好地使用索引,其中
CROSS JOIN
忽略用于筛选结果的有用索引,而是选择一个更好的索引来对结果进行排序,或者选择一个覆盖所有使用的字段的索引,因为假定表中的每个记录都将被使用。说到索引,如果这没有帮助,那就是下一个要考虑的问题。但由于我们不知道你已经有了什么索引,我在这里提出的任何建议都将是一个黑暗的机会。
qcbq4gxm3#
这里不需要单独的日历表。相反,使用
CONNECT BY LEVEL
:给定您提供的测试数据,这将生成结果
db<>在这里摆弄