Reputation: 9
Trying to get the 2nd to last part status but getting invalid identified on my_p
in subquery. What's wrong?
SELECT part AS my_p
,CASE WHEN ((SELECT MAX(status) AS status
FROM (SELECT status,
TO_CHAR(jn_datetime, 'DD-MON-YYYY HH24:MI:SS'),
RANK() OVER(ORDER BY TO_DATE(TO_CHAR(jn_datetime, 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS') DESC) my_row_num
FROM master
WHERE part = my_p
)
WHERE my_row_num = 2
AND ROWNUM < 2)) = 'I' THEN 'OK'
END
FROM tab1;
Upvotes: 0
Views: 1175
Reputation: 191265
You can't refer to a column alias - my_p
- in the same query except in an order-by clause, unless it's outside a subquery it's defined in (as you do with my_rownum
). You're trying to use it in an inner subquery, where it isn't yet really defined.
You could give the outermost tab1
a table alias and refer to that, but as Gordon mentioned there are issues with the levels of nesting, depending partly on which version you're using. (It still fails in 11gR2, but works in 18c; I forget if that changed in 12cR1 or 12cR2.)
It also doesn't really make send to convert jn_datetime
to a string and then back to a date.
You possibly want something like:
WITH cte (part, status, my_row_num) AS (
SELECT part,
status,
DENSE_RANK() OVER (PARTITION BY part ORDER BY jn_datetime DESC)
FROM master
)
SELECT t.part,
cte.status,
CASE WHEN cte.status = 'I' THEN 'OK' END AS flag
FROM tab1 t
LEFT JOIN cte ON cte.part = t.part AND cte.my_row_num = 2;
but it's hard to tell without sample data and results.
db<>fiddle with some brief made-up data based on what I think you're doing, your original query, this query, and just for fun, @Barbaros' query.
You might need to refine this if a part can have two master
rows with the same date/time.
Upvotes: 2
Reputation: 29
CASE WHEN ( SELECT MAX(status) AS status
FROM (SELECT status, part,
RANK() OVER (PARTITION BY part
ORDER BY jn_datetime DESC) AS my_row_num
FROM master
)
WHERE my_row_num = 2
AND ROWNUM < 2
AND part = t1.part ) = 'I'
THEN 'OK'
END AS status
FROM tab1 t1
Upvotes: 0
Reputation: 65218
You can rearrange the query like this
SELECT part AS my_p,
CASE WHEN ( SELECT MAX(status) AS status
FROM (SELECT status, part,
RANK() OVER (PARTITION BY part
ORDER BY jn_datetime DESC) AS my_row_num
FROM master
)
WHERE my_row_num = 2
AND ROWNUM < 2
AND part = t1.part ) = 'I'
THEN 'OK'
END AS status
FROM tab1 t1
in order to prevent the error due to correlated subquery which is not nested in this case. Btw, recursive conversion TO_CHAR()
, and then TO_DATE()
for jn_datetime
has no sense if this column is of date or timestamp type column. TO_CHAR(jn_datetime, 'DD-MON-YYYY HH24:MI:SS')
is redundant.
Upvotes: 2