Oracle SQL、return SELECT header 子查询中的唯一(最大)行(在 FROM、WHERE 之前)
Oracle SQL, return unique (max) row in subquery in SELECT header (before FROM, WHERE)
我在 Oracle 服务器上 运行 SQL 通过业务 Objects。我有以下代码(简化),有时会运行:
SELECT
a.col1,
a.col2,
a.date1,
(
SELECT
b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
) AS SUBDATE
FROM
tbl a
WHERE
a.col1 = 'foo'
AND
a.col2 = 'bar'
AND
a.date1 = '#somedate#'
因此,如您所见,SELECT 子句中有一个子查询,我想 return 单个值:b.date2。这确实有效……有时。但是,如果 b.ID returns 多条 条记录,其中 date2 在 date1 的最后 60 天内,则查询失败。
我想做的是将子查询的输出限制为 date2 的单个最新值。我尝试了各种方法:MAX、LIMIT 1、DISTINCT...但是 SQL 无法编译,告诉我有错误。例如下面的 TOP 1 会产生一个错误 "FROM keyword not found where expected":
(
SELECT
TOP 1 b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
) AS SUBDATE
下面的 ORDER BY/LIMIT 产生一个错误 "Missing right parenthesis":
(
SELECT
b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
ORDER BY b.date2 LIMIT 1
) AS SUBDATE
(只转载上面的子查询)。
通过研究这些错误,我看到了关于子查询的各种建议在 主 WHERE 子句之后;但是我想使用它们的方式与子查询无关。
任何人都可以帮助我理解为什么我会收到错误,以及正确的方法应该如何做我想做的事?
谢谢。
在这种情况下,Oracle 可能会很麻烦(除非您使用的是 Oracle 12)。一种方法使用 keep
。但是,在您的情况下 max()
就足够了:
SELECT . . .
(SELECT MAX(b.date2)
FROM tbl b
WHERE b.ID = a.ID AND
b.date2 >= a.date1 - 60
) AS SUBDATE
. . .
注意:您不需要子查询中的 date2
条件,除非您真的想将结果限制为最近 60 天。
我在 Oracle 服务器上 运行 SQL 通过业务 Objects。我有以下代码(简化),有时会运行:
SELECT
a.col1,
a.col2,
a.date1,
(
SELECT
b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
) AS SUBDATE
FROM
tbl a
WHERE
a.col1 = 'foo'
AND
a.col2 = 'bar'
AND
a.date1 = '#somedate#'
因此,如您所见,SELECT 子句中有一个子查询,我想 return 单个值:b.date2。这确实有效……有时。但是,如果 b.ID returns 多条 条记录,其中 date2 在 date1 的最后 60 天内,则查询失败。
我想做的是将子查询的输出限制为 date2 的单个最新值。我尝试了各种方法:MAX、LIMIT 1、DISTINCT...但是 SQL 无法编译,告诉我有错误。例如下面的 TOP 1 会产生一个错误 "FROM keyword not found where expected":
(
SELECT
TOP 1 b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
) AS SUBDATE
下面的 ORDER BY/LIMIT 产生一个错误 "Missing right parenthesis":
(
SELECT
b.date2
FROM
tbl b
WHERE
b.ID = a.ID
AND
b.date2 >= a.date1-60
ORDER BY b.date2 LIMIT 1
) AS SUBDATE
(只转载上面的子查询)。
通过研究这些错误,我看到了关于子查询的各种建议在 主 WHERE 子句之后;但是我想使用它们的方式与子查询无关。
任何人都可以帮助我理解为什么我会收到错误,以及正确的方法应该如何做我想做的事?
谢谢。
在这种情况下,Oracle 可能会很麻烦(除非您使用的是 Oracle 12)。一种方法使用 keep
。但是,在您的情况下 max()
就足够了:
SELECT . . .
(SELECT MAX(b.date2)
FROM tbl b
WHERE b.ID = a.ID AND
b.date2 >= a.date1 - 60
) AS SUBDATE
. . .
注意:您不需要子查询中的 date2
条件,除非您真的想将结果限制为最近 60 天。