2

このクエリを実行しています。

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])ことですが、コストがかかるようです。

最悪の場合、商品ごとに1つずつクエリを実行することもできますが、できればそれは避けたいです。

ありがとう、デーン

4

4 に答える 4

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;
于 2012-07-19T22:01:50.057 に答える
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」句を使用してクエリを1回含めるだけで済みます。

于 2012-07-19T22:08:59.117 に答える
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_id、どのテーブルにフィールドが含まれているかを推測しました。transaction_date

于 2012-07-19T21:52:56.963 に答える
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

これは、現在の行より後の日付の請求書が見つかった場合、その行を除外するという考え方です。余分な結合が正確に正しくない場合があります。主キーについていくつか推測しています。

于 2012-07-20T14:38:19.327 に答える