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 天。