从连接表中选择MAX(日期)

时间:2012-07-19 21:33:11

标签: mysql sql

我正在运行此查询。

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 ...);

结果表是:

quantity | transaction_date | product_id
7          2012-01-04         8000016F-1325198704
8          2012-03-05         8000016F-1325198704
1          2012-01-05         11111111-1324422404
...        ...                ...

我想为特定的product_id选择基于MAX(transaction_date)的行,以便得到这样的结果:

quantity | transaction_date | product_id
8          2012-03-05         8000016F-1325198704
1          2012-01-05         11111111-1324422404

换句话说,从联接表中,我想选择每个产品ID的最新条目。

我试过了:

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; 

但数量不正确。

我没想过的另一种方法,但我觉得可能有用,就是使用HAVING MAX(transaction_date) = ([sub query]),但这看起来很昂贵。

最糟糕的情况是,我可以逐个查看每个产品的查询,但如果可能,我想避免这样做。

谢谢, 戴恩

4 个答案:

答案 0 :(得分:2)

这应该做你要求的并且合理有效。在内循环中使用IN()检查产品,因此如果您对product_id和customer_id进行索引,则它应该运行得非常快。还建议在t1.invoice_id上​​建立索引。

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;

答案 1 :(得分:0)

这可以解决这个问题吗?

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
                         )

我猜测哪些表包含字段product_idtransaction_date,因为原始查询中不清楚这些字段。

答案 2 :(得分:0)

这是一个相对简单的配方

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

此解决方案仅要求您使用“with”子句包含您的查询一次。

答案 3 :(得分:0)

您的替代方案是子查询(由其他答案提供),或以下反连接(自连接):

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

我们的想法是,如果找到日期大于当前行的发票,则会排除该行。我可能没有完全正确的额外加入。我正在猜测主键。

相关问题