I want to select a single record with the latest value on the version column. However If I include the retrn_period
column which is of type date my query returns multiple records.
SELECT rdo_code, batch_no, reference_no, dln, retrn_seq_num, ftype_code, tin,
branch_code, tax_type, retrn_period, Max(version)
FROM rfp_returns_ref
WHERE tin = '000079108'
AND ftype_code = '1702EX'
AND Upper(status) = Upper('POSTED')
group by rdo_code, batch_no,reference_no, dln,
retrn_seq_num, ftype_code, tin, branch_code, tax_type, retrn_period;
If I include the retrn_period column ... my query returns multiple records.
By including the retrn_period
column you are changing the non-aggregated projection of the query, so now you get the maximum version for each distinct date in the result set.
You want to show the date of the latest version? Assuming your retrn_period
increases alongside the version
this would work:
SELECT rdo_code, batch_no, reference_no, dln, retrn_seq_num, ftype_code, tin,
branch_code, tax_type
, max(retrn_period) as retrn_period
, max(version) as version
FROM rfp_returns_ref
WHERE tin = '000079108'
AND ftype_code = '1702EX'
AND Upper(status) = Upper('POSTED')
group by rdo_code, batch_no,reference_no, dln,
retrn_seq_num, ftype_code, tin, branch_code, tax_type;
A more general solution which would work for something which can't be aggregate, say name
, would be to use a subquery with an analytic function...
SELECT sq.rdo_code, sq.batch_no, sq.reference_no, sq.dln, sq.retrn_seq_num, sq.ftype_code, sq.tin,
sq.branch_code, sq.tax_type
, sq.retrn_period
, sq.name
, sq.version
from (
SELECT rdo_code, batch_no, reference_no, dln, retrn_seq_num, ftype_code, tin,
branch_code, tax_type
, retrn_period
, version
, name
, rank() over (partition by rdo_code, batch_no,reference_no, dln,
retrn_seq_num, ftype_code, tin, branch_code, tax_type
order by version desc ) as rn
FROM rfp_returns_ref
WHERE tin = '000079108'
AND ftype_code = '1702EX'
AND Upper(status) = Upper('POSTED')
) sq
where sq.rn = 1 ;
If you're using Oracle 12c you can use the fetch limiting syntax, which is a lot simpler:
SELECT rdo_code, batch_no, reference_no, dln, retrn_seq_num, ftype_code, tin,
branch_code, tax_type
, retrn_period
, version
FROM rfp_returns_ref
WHERE tin = '000079108'
AND ftype_code = '1702EX'
AND order by version desc
fetch first 1 row only;
If you want to select a sinle record - with the highest version number - then I don't think you need to group any thing at all.
Ordering the rows by the version number and grabbing the top 1 should do it:
SELECT
rdo_code,
batch_no,
reference_no,
dln,
retrn_seq_num,
ftype_code,
tin,
branch_code,
tax_type
retrn_period,
version
FROM rfp_returns_ref
WHERE
tin = '000079108'
AND ftype_code = '1702EX'
AND UPPER(status) = UPPER('POSTED')
ORDER BY version DESC
FETCH FIRST 1 ROWS ONLY;
This query assumes that you are running Oracle 12c.
You can also use rownum=1
SELECT
rdo_code,
batch_no,
reference_no,
dln,
retrn_seq_num,
ftype_code,
tin,
branch_code,
tax_type
retrn_period,
version
FROM rfp_returns_ref
WHERE
tin = '000079108'
AND ftype_code = '1702EX'
AND UPPER(status) = UPPER('POSTED')
AND rownum=1
ORDER BY version DESC;
---------------------------------------------------------------------------------------
or subquery like
SELECT
rdo_code,
batch_no,
reference_no,
dln,
retrn_seq_num,
ftype_code,
tin,
branch_code,
tax_type
retrn_period,
version
FROM rfp_returns_ref a
WHERE
tin = '000079108'
AND ftype_code = '1702EX'
AND UPPER(status) = UPPER('POSTED')
AND a.version = (SELECT Max(b.version)
FROM rfp_returns_ref b
WHERE b.tin = a.tin
AND b.ftype_code = a.ftype_code
AND b.UPPER(status) = UPPER(a.status));
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.