Reputation: 463
I have two tables MASTER_TABLE
and DOCUMENTS
table. Both are related with a column reference_id. DOCUMENTS
table has columns doc_id
,doc_type
and doc_creation_date
We can have more than one entry in DOCUMENTS
table for each doc_type
with different doc_creation_date
. My aim is to fetch the doc_type
and doc_id
for each doc_type
in a single row for the max doc_creation_date
MASTER_TABLE
REFERENCE_ID COLUMN1 COLUMN2
1 DATA1 DATA2
2 DATA3 DATA4
3 DATA5 DATA6
DOCUMENTS
REFERENCE_ID DOC_ID DOC_TYPE DOC_CREATION_DATE
1 11 PDF 16/06/2017
1 12 XLS 16/06/2017
1 13 TXT 16/06/2017
1 14 PDF 15/06/2017
1 15 XLS 15/06/2017
1 16 TXT 15/06/2017
2 17 PDF 16/06/2017
2 18 XLS 16/06/2017
2 19 TXT 16/06/2017
EXPECTED OUTPUT
REFERENCE_ID DOC_ID_PDF DOC_ID_XLS DOC_ID_TXT
1 11 12 13
2 17 18 19
Is this possible to achieve using a single query. I tried a self join and pivot but guess am doing it the wrong way. We have Oracle 11g and 12c databases that we can use.
Upvotes: 1
Views: 81
Reputation: 162
Rank() Over([Partition by] Order by)
followed by Pivot
will solve your issue.
Following is the code. The following will get you the max doc_id in case multiple doc_ids have same max creation date. If you need the minimum doc_id for the above scenario, change the max
function to min
in pivot
clause.
WITH master_table AS
(SELECT 1 reference_id, 'DATA1' column1, 'DATA2' column2
FROM DUAL
UNION
SELECT 2 reference_id, 'DATA3' column1, 'DATA4' column2
FROM DUAL
UNION
SELECT 3 reference_id, 'DATA5' column1, 'DATA6' column2
FROM DUAL),
documents AS
(SELECT 1 reference_id, 11 doc_id, 'PDF' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 1 reference_id, 12 doc_id, 'XLS' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 1 reference_id, 13 doc_id, 'TXT' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 1 reference_id, 14 doc_id, 'PDF' doc_type,
'15/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 1 reference_id, 15 doc_id, 'XLS' doc_type,
'15/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 1 reference_id, 16 doc_id, 'TXT' doc_type,
'15/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 2 reference_id, 17 doc_id, 'PDF' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 2 reference_id, 18 doc_id, 'XLS' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL
UNION
SELECT 2 reference_id, 19 doc_id, 'TXT' doc_type,
'16/06/2017' doc_creation_date
FROM DUAL)
SELECT *
FROM (SELECT reference_id, doc_id, doc_type
FROM (SELECT x.reference_id, y.doc_id, y.doc_type,
y.doc_creation_date,
RANK () OVER (PARTITION BY x.reference_id, y.doc_type ORDER BY y.doc_creation_date DESC)
RANK
FROM master_table x JOIN documents y
ON (x.reference_id = y.reference_id)
)
WHERE RANK = 1)
pivot (max(doc_id)
FOR doc_type
IN ( 'PDF' doc_id_pdf, 'XLS' doc_id_xls,'TXT' doc_id_txt));
Upvotes: 1