Reputation: 2263
I am running this query.
SELECT
t1.quantity,
t2.transaction_date,
t1.product_id
FROM
ezsystem_usah.invoice_line AS t1
INNER JOIN ezsystem_usah.invoices AS t2
ON t1.invoice_id = t2.id_invoices
WHERE
t2.customer_id = '8000004C-1325619329'
AND ( product_id = '8000016F-1325198704'
OR product_id = '80000027-1324422404' OR ...);
The resulting table is:
quantity | transaction_date | product_id
7 2012-01-04 8000016F-1325198704
8 2012-03-05 8000016F-1325198704
1 2012-01-05 11111111-1324422404
... ... ...
I would like to select rows based upon MAX(transaction_date) for a particular product_id, in order to yield something like this:
quantity | transaction_date | product_id
8 2012-03-05 8000016F-1325198704
1 2012-01-05 11111111-1324422404
In other words, from the joined table, I want to select the latest entry of EACH product id.
I have tried:
SELECT
t1.quantity,
MAX(t2.transaction_date),
t1.product_id
FROM
ezsystem_usah.invoice_line AS t1
INNER JOIN ezsystem_usah.invoices AS t2 ON t1.invoice_id = t2.id_invoices
WHERE
t2.customer_id = '8000004C-1325619329'
AND (product_id = '8000016F-1325198704' OR product_id = '80000027-1324422404' OR ...)
GROUP BY
t1.product_id;
However the quantity is incorrect.
Another way I haven't tried but I think might work is to use HAVING MAX(transaction_date) = ([sub query])
, but it seems costly.
Worst case, I can run queries for each product one by one, but I'd like to avoid that if possible.
Thanks, Dane
Upvotes: 2
Views: 993
Reputation: 53830
Your alternatives are sub queries (as provided by in other answers), or the following anti-join (self-join):
SELECT
t1.quantity,
t2.transaction_date,
t1.product_id
FROM
ezsystem_usah.invoice_line AS t1
INNER JOIN ezsystem_usah.invoices AS t2
ON t1.invoice_id = t2.id_invoices
LEFT JOIN ezsystem_usah.invoices AS t3
ON t3.transaction_date > t2.transaction_date
AND t3.id_invoices = t2.id_invoices
WHERE
t2.customer_id = '8000004C-1325619329' AND
(t1.product_id = '8000016F-1325198704' OR t1.product_id = '80000027-1324422404' OR ...) AND
t3.id_invoices IS NULL
GROUP BY
t1.product_id
The idea is that if invoices with dates greater than the current row are found, it excludes the row. I may not have the extra join exactly right. I'm making some guesses about the primary key.
Upvotes: 0
Reputation: 847
Does this do the trick?
SELECT
t1.quantity,
transaction_date,
product_id
FROM
ezsystem_usah.invoice_line AS t1
INNER JOIN ezsystem_usah.invoices AS t2 ON t1.invoice_id = t2.id_invoices
WHERE
t2.customer_id = '8000004C-1325619329'
AND product_id IN ( '8000016F-1325198704', '80000027-1324422404' )
AND transaction_date = ( SELECT MAX( inv.transaction_date )
FROM ezsystem_usah.invoices inv
INNER JOIN ezsystem_usah.invoice_line ln
ON inv.customer_id = t2.customer_id
AND ln.invoice_id = inv.id_invoices
AND ln.product_id = t1.product_id
)
I took a guess which tables contain the fields product_id
and transaction_date
as it's not clear from the original query.
Upvotes: 0
Reputation: 1269513
Here is a relatively simple formulation
with t as (<your query here>)
select t.*
from t join
(select t.product_id, max(t.transaction_date) as maxdate
from t
group by t.product_id
) tmax
on t.product_id = tmax.product_id and
t.transaction_date = tmax.maxdate
This solution only requires you to include your query once, using the "with" clause.
Upvotes: 0
Reputation: 57388
This should do what you ask for and be reasonably efficient. Products are checked with IN () in the inner loop, so if you have indexing on product_id and customer_id it should run pretty fast. Indexing on t1.invoice_id is also recommended.
SELECT
t1.quantity,
transaction_date,
product_id
FROM
ezsystem_usah.invoice_line AS t1
JOIN (
SELECT t3.transaction_date, t3.product_id, t3.id_invoices
FROM ezsystem_usah.invoices t3
JOIN
( SELECT MAX(transaction_date) AS max_transaction_date,
product_id
FROM ezsystem_usah.invoices
WHERE product_id IN (
'8000016F-1325198704', '80000027-1324422404'
)
AND customer_id = '8000004C-1325619329'
GROUP BY product_id ) AS uniqued
ON ( t3.transaction_date = uniqued.max_transaction_date
AND t3.product_id = uniqued.product_id
)
) AS t2
ON t1.invoice_id = t2.id_invoices;
Upvotes: 2