まず、インターネットで適切な解決策を見つけようとしましたが、実際に自分に合った解決策は見つかりませんでした。私の問題は何だと思われますか?上手...
私の新しい仕事では、MySQLを使用しています。私はDB2とSQLServerでの作業に慣れているので、一般的なテーブル式(cte)を使用したり、テーブルを適切に結合したりできないことに非常に驚いていました。たとえば、(サブ)テーブルを2番目のfromステートメントとして作成している間は、最初のfromステートメントのデータを使用して2つのテーブルを接続することはできません。動作するのは、(sub)テーブルで最初のfromステートメントを再度使用することですが、2番目のfromステートメントの(sub)テーブルの結果を使用する必要がある3番目のテーブルを追加すると、エラー。 :-(
私の質問を単純化するために。顧客データの表があります。お客様はそれぞれ異なります。私はお客様の番号と名前を使用します。また、一意の顧客ごとに複数の請求書とそれらの請求書の日付が記載された請求書テーブルもあります。最後に、すべての収益データを含む収益テーブルがあります。複数の行が可能で、収益が予約される日付があります。
ここで(これも単純化された例です)、請求書テーブルから最大日付を取得し、その日付を使用して、その日付以降の収益のみを取得したいと思います。そして、クエリ全体の結果として、顧客番号、顧客名、最大請求日、収益の合計を取得します。
以前は、fromステートメントで共通テーブル式または(サブ)テーブルを使用して最大日付を実行し、これを3番目のfromステートメントの収益日>最大請求日で使用していました。しかし、これをMySQL内で機能させるにはどうすればよいですか?これは単純な例ですが、複雑になったときにこのようなことをどのように行いますか?
どんな助けでも大歓迎です!ありがとう。
クエリの例:
select *
from table_A t1
join table
( select t0.customernumber, max(t0.date) as max_date
from table_B t0
where t1.customernumber = t0.customernumber
) t2
on t1.customernumber = t2.customernumber
join table_C t3
on t1.customernumber = t3.customernumber
and t3.date > t2.max_date
テーブル構造がないと、コードを書くのは簡単ではありませんが、簡単なクエリを次に示します。
_SELECT
c.*, i.*,
r.max_date
FROM
customer AS c
LEFT JOIN -- or just JOIN
( SELECT customernumber,
MAX(revenue_date) AS max_date
FROM revenue
GROUP BY customernumber
) AS r
ON r.customernumber = c.customernumber
LEFT JOIN -- or just JOIN
invoice AS i
ON i.customernumber = c.customernumber
AND i.invoice_date >= r.max_date ;
_
上記は標準SQLであり、他のすべてのDBMSと同様にMySQLでも機能します。ただし、LATERAL
または同様の構文を使用してよりエレガントな(またはより効率的な)SQLを提供できる、より複雑な状況では、MySQLは役に立ちません。標準のSQL構文の多くが欠けています(一般的なテーブル式、テーブル値コンストラクター、ウィンドウ関数、LATERAL
、CHECK
制約、そしておそらく私が忘れている他のいくつかのような)。
(SQL-Serverの)_OUTER APPLY
_、(ISO/ANSI)LATERAL
、または(DB2の)TABLE
構文をシミュレートする場合、(悪いニュース)は非常に複雑になりますが、(良いニュース)通常、適切なインデックス付けで非常に効率的です。これは主に、小さな「ベース」テーブル(この場合はcustomer
)がある場合、またはクエリをWHERE
句を持つ少数の顧客のみに制限する場合に役立ちます。上記の_GROUP BY
_を使用したクエリでは、すべての顧客のMAX(revenue_date)
を見つける必要があります(つまり、revenue
の完全なテーブルまたは完全なインデックススキャンを意味します)。選択された少数の顧客の最大値のみが検出されます(したがって、いくつかのインデックスがシークします)。
_SELECT
c.*, i.*,
r.revenue_date AS max_date
FROM
customer AS c
LEFT JOIN
revenue AS r
ON r.customernumber = .customernumber
AND r.PK =
( SELECT ri.PK
FROM revenue AS ri
WHERE ri.customernumber = c.customernumber
ORDER BY ri.revenue_date DESC
LIMIT 1
)
LEFT JOIN
invoice AS i
ON i.customernumber = c.customernumber
AND i.invoice_date >= r.revenue_date
WHERE
<some conditions on the customer table> ;
_
revenue
リストにSELECT
テーブルの任意の列を含めることができることです。(customernumber, revenue_date)
_が一意である場合、結合の主キーの代わりに_revenue_date
_を使用できるなど、いくつかの改善/バリエーションがあります。TOP n
_クエリ)が必要な場合は、非常に複雑になりますが、それでも実行できます。