简体   繁体   中英

Oracle SQL, return unique (max) row in subquery in SELECT header (before FROM, WHERE)

I am running SQL through Business Objects on an Oracle server. I have the following code (simplified), which sometimes runs:

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#'

So as you see, there is a subquery in the SELECT clause, which I want to return a single value: b.date2. This does work... some of the time. However, if b.ID returns more than one record where date2 is within the last 60 days of date1, then the query fails.

What I want to do is to limit the subquery's output to the single most recent value of date2. I have tried all sorts of things: MAX, LIMIT 1, DISTINCT... however the SQL will not compile, telling me that I have errors. For example the following TOP 1 produces an error saying "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

The following ORDER BY/LIMIT produces an error saying "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

(Reproduced subqueries only above).

From researching these errors, I see various advice about subqueries after the main WHERE clause; however nothing about subqueries in the way I want to use them.

Can anyone help me understand why I am getting errors, and what the correct way should be do do what I want?

Thanks.

Oracle can be a pain in this case (unless you are using Oracle 12). One method uses keep . However, in your case max() is sufficient:

SELECT . . . 
     (SELECT MAX(b.date2)
      FROM tbl b
      WHERE b.ID = a.ID AND
            b.date2 >= a.date1 - 60
     ) AS SUBDATE
. . .

Note: You don't need the condition on date2 in the subquery, unless you really want to limit results to the last 60 days.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM