2

次のコードはすべての請求書を一覧表示します。ベンダーからの最も古い請求書が必要です。

SELECT DISTINCT vendor_name, i.invoice_number AS OLDEST_INVOICE, 
    MIN(i.invoice_date), i.invoice_total
FROM vendors v
JOIN invoices i
ON i.vendor_id = v.vendor_id
GROUP BY vendor_name, invoice_number, invoice_total
ORDER BY MIN(i.invoice_date);
4

4 に答える 4

2

ROW_NUMBER()仕入先ごとに日付で請求書を「ランク付け」し、仕入先ごとに最も古いもののみを選択するために使用します。

SELECT vendor_name, invoice_number AS oldest_invoice, invoice_date, invoice_total
  FROM vendors v
 INNER JOIN (SELECT invoices.*,
                    ROW_NUMBER() OVER (PARTITION BY vendor_id ORDER BY invoice_date ASC)
                      AS rn
               FROM invoices) i
       ON i.vendor_id = v.vendor_id
          AND
          i.rn = 1;
于 2012-11-04T22:36:36.787 に答える
1

TDQD の時間 — テスト駆動型クエリ設計

各ベンダーの請求書の最短日付は、次の式で与えられます。

SELECT vendor_id, MIN(invoice_date) AS invoice_date
  FROM invoices
 GROUP BY vendor_id

対応する最小請求書番号 (ベンダーが請求された最初の日に複数の請求書が送信された可能性がある場合、invoice_dateが時間コンポーネントのない真の DATE である場合; DATE に時間コンポーネントが含まれている場合、2 番目の MIN() はおそらく不要)、次のとおりです。

SELECT vendor_id, MIN(invoice_number) AS invoice_number
  FROM invoices AS i
  JOIN (SELECT vendor_id, MIN(invoice_date) AS invoice_date
          FROM invoices
         GROUP BY vendor_id
       ) AS j ON j.vendor_id = i.vendor_id AND j.invoice_date = i.invoice_date
 GROUP BY vendor_id

クエリの要件に合わせて、この式を他のテーブルと結合できます。

SELECT v.*, i.*
  FROM vendors AS v
  JOIN (SELECT vendor_id, MIN(invoice_number) AS invoice_number
          FROM invoices AS i
          JOIN (SELECT vendor_id, MIN(invoice_date) AS invoice_date
                  FROM invoices
                 GROUP BY vendor_id
               ) AS j ON j.vendor_id = i.vendor_id AND j.invoice_date = i.invoice_date
         GROUP BY vendor_id
       ) AS inv_info ON v.vendor_id = inv_info.vendor_id
  JOIN invoices AS i ON i.invoice_number = inv_info.invoice_number

間違いなく、それを設計する他の方法があります。これらのサブクエリはいずれも相関サブクエリではないことに注意してください。

TDQD は純粋に名目上のものです。これらのクエリが構文的に有効であるかどうかをチェックするのに苦労した DBMS はありませんでした。OTOH、立ち技です。

GROUP BY 句に多数の列をリストするのが好きな場合は、サブクエリで関連する請求書の列を返すようにするinvoicesことで、最後の結合を行わなくても済みます。inv_infoたくさんの列名を書き出すのは好きではありませんが、パフォーマンスが気になる場合は、それが有意な違いを生むかどうかを測定します。

記法上より速く仕事をする OLAP 関数/クエリがあることに気付くかもしれません。

于 2012-11-04T22:18:31.100 に答える
0

ここでは機能しませんHAVINGか?

SELECT DISTINCT vendor_name, i.invoice_number AS OLDEST_INVOICE, 
    MIN(i.invoice_date), i.invoice_total
FROM vendors v
JOIN invoices i
ON i.vendor_id = v.vendor_id
GROUP BY vendor_name, invoice_number, invoice_total
HAVING i.invoice_date = MIN (i.invoice_date)
ORDER BY MIN(i.invoice_date);
于 2012-11-04T21:30:40.313 に答える
0

代わりにこれを試してください:

SELECT DISTINCT 
    v.vendor_name, 
    i.invoice_number AS OLDEST_INVOICE, 
    i2.MinDate, 
    i.invoice_total
FROM vendors v
INNER JOIN invoices i  ON i.vendor_id = v.vendor_id
INNER JOIN
(
    SELECT 
      invoice_number , 
      MIN(i.invoice_date) MinDate
    FROM invoices
    GROUP BY invoice_number
) i2 ON  i.invoice_number = i2.invoice_number
     AND i.invoice_date   = i2.MinDate
ORDER BY i2.MinDate;
于 2012-11-04T21:24:34.780 に答える