如何在Oracle中执行基于ORDER BY
子句返回第一个匹配行的相关子查询?我正在尝试从执行此操作的SQL Server转换查询。
为了记录,我需要坚持(主要)SQL-92语法。根本不应该使用分析函数,我需要尽量减少使用非标准SQL。 TOP 1 ... ORDER BY
是SQL Server专有的,我正在努力将其翻译为rownum
。
注意:已经指出此特定查询不需要TOP/LIMIT/rownum
,因为它在语义上等同于使用Min()
,因为我们只需要一列。但我仍然会欣赏并会奖励任何有关如何执行翻译的帮助 - 因为我想更好地学习Oracle。
这是SQL Server查询(以及SqlFiddle for it):
SELECT
D.StartDate,
(
SELECT TOP 1 E.EndDate
FROM dbo.Dates E
WHERE
E.EndDate >= D.EndDate
AND NOT EXISTS (
SELECT *
FROM dbo.Dates E2
WHERE
E.StartDate < E2.StartDate
AND E.EndDate > E2.StartDate
)
ORDER BY
E.EndDate,
E.StartDate DESC
) EndDate
FROM
dbo.Dates D
WHERE
NOT EXISTS (
SELECT *
FROM dbo.Dates D2
WHERE
D.StartDate < D2.EndDate
AND D.EndDate > D2.EndDate
);
这是我尝试过的。我受到了阻碍,因为我在D.EndDate
外部参考上收到错误。
ORA-00904:“D”。“ENDDATE”:标识符无效
但是问题是什么? SELECT
子句中的相关子查询应该可以访问所有外部表数据。我不知道下一步该往哪里去。 (和the SqlFiddle for this)。
SELECT
D.StartDate,
(
SELECT *
FROM (
SELECT E.EndDate
FROM Dates E
WHERE
E.EndDate >= D.EndDate
AND NOT EXISTS (
SELECT *
FROM Dates E2
WHERE
E.StartDate < E2.StartDate
AND E.EndDate > E2.StartDate
)
ORDER BY
E.EndDate,
E.StartDate DESC
)
WHERE rownum = 1
) EndDate
FROM
Dates D
WHERE
NOT EXISTS (
SELECT *
FROM Dates D2
WHERE
D.StartDate < D2.EndDate
AND D.EndDate > D2.EndDate
);
答案 0 :(得分:1)
我可能会遗漏某些内容,但您不能使用MIN
代替TOP 1 ... ORDER BY
,因为您通过EndDate,StartDate DESC订购,并且只选择EndDate,开始日期与排序,只有当你有2个结束日期相同时才考虑它,但由于你只选择结束日期,所以使用两个(或更多结束日期)中的哪一个并不重要:
SELECT D.StartDate,
( SELECT MIN(E.EndDate)
FROM Dates E
WHERE E.EndDate >= D.EndDate
AND NOT EXISTS
( SELECT 1
FROM Dates E2
WHERE E.StartDate < E2.StartDate
AND E.EndDate > E2.StartDate
)
) EndDate
FROM Dates D
WHERE NOT EXISTS
( SELECT 1
FROM Dates D2
WHERE D.StartDate < D2.EndDate
AND D.EndDate > D2.EndDate
);
<强> Example on SQL Fiddle 强>