MySQL - この場合、単一の SQL リクエストを作成するにはどうすればよいですか?

okwaves2024-01-25  6

次の SQL リクエストに対する解決策を何日も探し続けましたが、成功しませんでした。

私の状況:

テーブルが 3 つあります (リンク: https://i.stack.imgur.com/BswG0.png)

企業 (企業を含む) リクエスト: 企業から送信されたリクエストが含まれます オファー: 企業から送信されたリクエストに対するオファーだけでなく、企業に直接送信された自発的なオファーも含まれます。

テーブル Offers には 2 つの外部キーが含まれています:

オファー_fk_companies オファー_fk_requests

オファーが企業から送信されたリクエストにリンクされている場合、フィールド Offers_fk_requests には値が含まれ、フィールド Offers_fk_companies は null になります。

オファーがリクエストなしで企業に直接送信される場合、フィールド Offers_fk_requests は null で、フィールドはオフになりますrs_fk_companies には値が含まれています。

オファー テーブルに対して SELECT を実行して、(リクエストなしで)企業に直接送信されたオファーのすべてのエントリを取得したいと思います。また、企業からのリクエスト後に送信されたオファーのエントリも取得したいと考えています。

私はこのリクエストを持ってきました:

SELECT *
FROM `offers`

LEFT JOIN `requests` ON `offers_fk_requests` = requests.`id`
JOIN `companies` AS companies1 ON requests.`fk_companies` = companies1.`companies_id`

LEFT JOIN `companies` AS companies2 ON offers.`fk_companies` = companies2.`companies_id`

WHERE ...

上記のリクエストを実行した場合と、2 つの異なるリクエストに分けた場合では異なる結果が得られます。

SELECT *
FROM `offers`

LEFT JOIN `requests` ON `offers_fk_requests` = requests.`id`
JOIN `companies` AS companies1 ON requests.`fk_companies` = companies1.`companies_id`

WHERE ...
SELECT *
FROM `offers`

LEFT JOIN `companies` AS companies2 ON offers.`fk_companies` = companies2.`companies_id`

WHERE ...

基本的に、2 つの異なるパスがあります。1 つはテーブル オファーからテーブル会社に行くパス、もう 1 つはテーブル オファーからテーブル会社に行くが、中間のテーブル リクエストを経由するパスです。

これらの個別のリクエストを組み合わせた場合と同じ結果を、単一のリクエストで達成するにはどうすればよいですか?

フィールドの数が異なるため、UNION は使用できません。しらないうーん、他に解決策はどこにあるでしょうか...

よろしくお願いします。

編集

元のリクエストに従い、すべての結合に LEFT OUTER JOIN を使用すると、機能するようです。

選択 * オファーから

LEFT OUTER JOIN リクエスト ON Offers_fk_requests =requests.id LEFT OUTER 企業を企業 1 として結合します request.fk_companies = Companies1.companies_id

LEFT OUTER JOIN Companies AS Companies2 ON Offers.fk_companies = Companies2.companies_id

どこ ...

@Marcel: 正しい方向に導いていただき、ありがとうございます!

こんにちは、ようこそe スタックオーバーフロー上。これはよく準備された完全な質問です!

– マルセル

2020 年 9 月 3 日 10:44

オファーに興味があると言うとき、そもそもなぜ参加したいのですか?オファーを選択し、含まれている外部キーのみに基づいてフィルタリングを実行できます。

– マルセル

2020 年 9 月 3 日 10:45

@マルセル。コメントありがとうございます。一致するすべてのエントリを 1 つの SQL リクエストで取得する必要があります。これは、日付に従ってエントリを並べ替える必要があることと、アプリケーション内でエントリを個別に表示することが意味がないためです。エントリは混合する必要があります。

– ジャン・ネマール

2020 年 9 月 3 日 10:47



------------------------

すべてを一度に行う必要があるという OP のコメントに基づいて、単純に実行することをお勧めします

SELECT * 
FROM offers
LEFT OUTER JOIN companies ON companyId /*simplified*/
LEFT OUTER JOIN requests ON requestId /*simplified*/

左外部結合は、一致する場合にのみデータを結合し、一致しない場合はフィールドを空のままにします。したがって、利用可能な Fi が得られ、すべてのオファーが得られることになります。フィールドは埋められています。

ただし、現在の設計では、リクエストがあるものについては、会社データが空になります。リクエストに基づくものにも会社の外部キーを設定し、このキーを必須にすることをお勧めします。いずれにせよ、リクエストのせいで、彼らは会社と結びついています。

3

あなたの提案をテストしたところです。それは機能しますが、すべてのオファーについて、不要な情報を含む膨大な結果セットが得られます。したがって、あなたの解決策は残念ながら私の状況には適切ではありません。

&ndアッシュ ジャン・ネマール

2020 年 9 月 3 日、11:20

リクエスト内で何らかの条件を使用して、次のような最終リクエストを作成することは可能でしょうか: IF fieldA is null then do request1 ELSE do request2?リクエストで条件を使用したことがないので、すべてが初めてで、それが可能かどうかさえわかりません。

– ジャン・ネマール

2020 年 9 月 3 日 11:29

2 つの異なるリクエストが必要な場合でも問題ありません。ただし、どちらを行うかはデータベースではなくアプリケーションで決定する必要があります。

– マルセル

2020 年 9 月 3 日 14:23



------------------------

UNION を使用する場合、欠落しているフィールドには NULL を入力できます。

SELECT *
FROM `offers`

LEFT JOIN `requests` ON `offers_fk_requests` = requests.`id`
JOIN `companies` AS companies1 ON requests.`fk_companies` = companies1.`companies_id`
UNION ALL SELECT null, null, null, `fk_companies`, `companies_id`
FROM `offers`

LEFT JOIN `companies` AS companies2 ON offers.`fk_companies` = companies2.`companies_id`
WHERE `companies_id` IS NOT NULL;

同じ列内のすべての Companies_id を取得するには、次のクエリを使用できます。

SELECT `requests`.`id` AS `requests_id`, coalesce(`requests`.`fk_companies`, `companies`.`companies_id`) AS `companies_id`
FROM `offers`

LEFT JOIN `companies` ON `offers`.`fk_companies` = `companies`.`companies_id`
LEFT JOIN `requests` ON `offers`.`offers_fk_requests` = `requests`.`id`;

db フィドルを参照してください。

0

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。