I have two tables, dochist and docarchive which contain document details for an order. I need to get the earliest Delivery Confirmation document (DOCTYPE = 35 and DOCNAME = 'Delivery Confirmation') for an order number from the dochist table. The problem is that it is possible for there to be one than one Delivery Confirmation for an order, but I am only interested in the earliest record. Once I have that, I need to fetch the binary image from the docarchive table.
My query code is below:
`SELECT h.ORDNO
,h.DOCNAME
,d.RECID
,d.DOCDATE
,a.DOCUMENT
FROM (
SELECT RECID, ORDNO
,MIN(DATE) AS DOCDATE
FROM dochist
WHERE DOCTYPE = 35
AND DOCNAME = 'Delivery Confirmation'
GROUP BY ORDNO, RECID
) d
INNER JOIN [ihdocarchive].[dbo].[DocArchive] a
ON a.PARID = d.RECID
INNER JOIN dochist h
ON h.RECID = a.PARID
ORDER BY h.ORDNO`
But this returns duplicates where there is more than one Delivery Confirmation for an order number:
what is RecID?? Looks like that might be PK of the table in which case you would want to use min(RecID) in your query. Something like this:
SELECT h.ORDNO
,h.DOCNAME
,d.RECID
,d.DOCDATE
,a.DOCUMENT
FROM (
SELECT
min(RECID) RECID
, ORDNO
,MIN(DATE) AS DOCDATE
FROM dochist
WHERE DOCTYPE = 35
AND DOCNAME = 'Delivery Confirmation'
GROUP BY ORDNO
) d
INNER JOIN [ihdocarchive].[dbo].[DocArchive] a
ON a.PARID = d.RECID
INNER JOIN dochist h
ON h.RECID = a.PARID
I've just tried exactly as per your suggestion and this seems to work so far as I've checked. So thank you - I have another similar one to do now, so will apply similar logic to that and hopefully it will work!
SELECT h.ORDNO
,h.DOCNAME
,d.RECID
,d.DOCDATE
,d.DOCUMENT
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ORDNO, RECID ORDER BY DATE) AS row_num
FROM dochist
) d
INNER JOIN [ihdocarchive].[dbo].[DocArchive] a
ON a.PARID = d.RECID
INNER JOIN dochist h
ON h.RECID = d.RECID
WHERE d.row_num = 1
ORDER BY h.ORDNO
You need to add the criteria in the derived table to limit the documents returned to only those that meet the requirement and order the row number by DOCDATE to get the earliest version of that document.
SELECT h.ORDNO
,h.DOCNAME
,d.RECID
,d.DOCDATE
,d.DOCUMENT
FROM (
SELECT *, ROW_NUMBER() OVER(PARTITION BY ORDNO, RECID ORDER BY DOCDATE) AS row_num
FROM dochist
WHERE DOCTYPE = 35
AND DOCNAME = 'Delivery Confirmation') d
INNER JOIN [ihdocarchive].[dbo].[DocArchive] a
ON a.PARID = d.RECID
INNER JOIN dochist h
ON h.RECID = d.RECID
WHERE d.row_num = 1
ORDER BY h.ORDNO
Sorry, I meant include the WHERE conditions in the inner query.
But there is no reason to re-join to the main table ("dochist") again. All the columns are available from the inner query. That is the point of using row_number.