I have two tables, ‘INVOICES’ contains invoice information and ‘CSEML’ contains customer email addresses. The email address type (field EMLTP) could be designated as ‘AP’ (Accounts Payable), ‘PO’ (Purchasing), or blank (default). Each customer could have 3 email addresses in CSEML (one for each designation). I’d like to be able to do this within the query: join the invoice table to the email table and pull a maximum of one email address per invoice – the AP address if it is defined, otherwise the PO address if it is defined, otherwise the default address if defined, otherwise null.
CSEML is structured like this
CUSTNO,EMLTP,EMAIL
000989367,PO,po@example.com
000254785,PO,po@example3.com
000989367,,default@example.com
000112354,,default@example2.com
000989367,AP,ap@example.com
000254785,,default@example3.com
Right now I have the following query
SELECT I.INVNO, I.CUSTNO, E.EMAIL
FROM INVOICES I
LEFT JOIN CSEML E ON I.CUSTNO = E.CUSTNO
WHERE I.INVNO = '10124'
Which returns something like this when there are all 3 addresses defined:
10124 000989367 po@example.com
10124 000989367 default@example.com
10124 000989367 ap@example.com
How can I assign a weight to the different email ‘types’ so that I’m only getting the most preferred address available?
Working Code based on accepted answer
SELECT INVNO, CUSTNO, EMAIL
FROM(
SELECT I.INVNO, I.CUSTNO, E.EMAIL, ROW_NUMBER() OVER (PARTITION BY I.INVNO
ORDER BY
CASE WHEN E.EMLTP = 'AP' THEN 0
WHEN E.EMLTP = 'PO' THEN 1
ELSE 2 END) rn
FROM INVOICES I
LEFT JOIN CSEML E ON I.CUSTNO = E.CUSTNO
WHERE I.INVNO = '10124'
) t
WHERE t.rn = 1
Advertisement
Answer
You may try using ROW_NUMBER
here with a CASE
expression to order/prioritize the email addresses of each invoice:
SELECT INVNO, CUSTNO, EMAIL
FROM
(
SELECT I.INVNO, I.CUSTNO, E.EMAIL, ROW_NUMBER() OVER (PARTITION BY I.INVNO
ORDER BY
CASE WHEN E.EMAIL LIKE 'ap@%' THEN 0
WHEN E.EMAIL LIKE 'po@%' THEN 1
ELSE 2 END) rn
FROM INVOICES I
LEFT JOIN CSEML E
ON I.CUSTNO = E.CUSTNO
WHERE I.INVNO = '10124'
) t
WHERE t.rn = 1;