sql >> データベース >  >> RDS >> Mysql

ネストされたビューの使用を回避するためにこのクエリを改善するにはどうすればよいですか?

    所有しているデータをよく理解してください:

    最初に重要なことは、あなたが持っているデータを理解することです。この場合、4つのテーブルがあります

    • InsuranceCompanies
    • 患者
    • 医師
    • 訪問

    あなたの目標:

    保険会社に関連するすべての整形外科医(専門医)を訪問したすべての患者のリストを検索します。

    一歩下がって、少しずつ分析してみましょう:

    一般的に、全体として見ると、要件は少し圧倒されるかもしれません。要件をより小さなコンポーネントに分割して、何をする必要があるかを理解しましょう。

    1. パートa: 「整形外科医」を専門とする医師のリストを見つける必要があります
    2. パートb: #1で特定された医師を訪問した患者のリストを見つけます。
    3. パートc: 結果#2をフィルタリングして、同じ保険会社を共有する患者と医師のリストを見つけます。
    4. パートd: それらの整形外科医のそれぞれを訪問した患者を見つけてください 患者と同じ保険会社に所属している人。

    アプローチ方法:

    1. ここでは、患者のリストを特定するために、主な目標を特定する必要があります。したがって、最初に患者テーブルをクエリします。

    2. あなたには患者がいますが、実際にはすべての患者がいますが、これらの患者のどれが医者を訪れたかを見つける必要があります。医者が整形外科医であるかどうかを心配しないでください。必要なのは、患者と彼らが訪れた医師のリストだけです。 PatientテーブルとDoctorsテーブルの間にマッピングはありません。この情報を見つけるには、

      正しいキーフィールドのVisitsテーブルでPatientテーブルに参加します。

      次に、出力を正しいキーフィールドのDoctorsテーブルと結合します。

    3. 正しく参加すると、訪問したすべての患者と医師のリストが表示されます。 LEFT OUTER JOINを使用した場合 、あなたは医者を一度も訪れたことがない患者さえ見つけるでしょう。 RIGHT OUTER JOINを使用した場合 、医師を訪問した患者のみが表示されます。

    4. これで、訪問したすべての患者と医師ができました。ただし、要件は、整形外科医である医師のみを見つけることです。 。したがって、条件を適用して結果をフィルタリングし、目的の結果のみを取得します。

    5. これで、パートaでより小さなコンポーネントに分割された要件を達成しました。 およびパートb 。あなたはまだ保険会社によってそれをフィルタリングする必要があります。ここで注意が必要な部分があります。要件では、保険会社を表示する必要があるとは規定されていないため、InsuranceCompaniesテーブルを使用する必要はありません。次の質問は、'How am I going to filter the results?'になります。 。有効なポイント。 3つのテーブルのいずれかがPatientであるかどうかを確認します 、Doctor およびVisits 保険会社の情報が含まれています。 Patient およびDoctors 共通のフィールドがあります。その共通フィールドに参加して、結果をフィルタリングします。

    6. ユニークな整形外科医の数を探す 各患者が訪れたこと。

    7. これは多くの方法で実行できる部分です。これを実行する方法の1つは、出力の4番目の列となるサブクエリを追加することです。このサブクエリは、テーブルDoctorsにクエリを実行し、specialty='Orthopedist'でフィルタリングします。そのフィルターに加えて、内部テーブルの保険会社を、メインクエリにあるPatientsテーブルの保険会社IDと照合してフィルタリングする必要もあります。このサブクエリは、患者のデータと一致する保険会社IDのすべての整形外科医の数を返します。

    8. これで、patient idフィールドが表示されます。 、patient namepatients visits count およびtotal number of Orthopedists in same insurance company サブクエリから。次に、patients visits countのフィールドでこの派生テーブルの結果をフィルタリングする外部結合を追加できます。 total number of Orthopedists in same insurance companyと一致します 。これが最善のアプローチだと言っているのではありません。これは私が考えることができる1つのアプローチです。

    9. 上記のロジックに従うと、これが必要になります。

    すべての医師を訪問した患者のリスト

    整形外科医である医師のみによってフィルタリングされます

    同じ保険会社の情報を共有する患者と医師によってフィルタリングされます。

    この場合も、出力全体は、派生テーブル出力内にある2つのカウントフィールドによってフィルタリングされます。

    ボールはコートにあります:

    • 段階的に試して、答えが見つかったら。別の回答としてここに投稿してください。この質問に対するすべての反対票を補うために、賛成票を投じます。

    これは簡単にできると確信しています。

    つまずいたら...

    comments to this answerとして質問を投稿することを躊躇しないでください 、その他と私は喜んでお手伝いします。

    免責事項

    このロジックを実装する方法の1つを提供しました。これをはるかに優れた方法で実装する方法はたくさんあると確信しています。

    結果:

    目的の出力を生成する正しいクエリについては、@OfekRonの回答を参照してください。クエリのどの部分も書きませんでした。それはすべてOPの努力でした。



    1. MySQL:クエリ結果に列を動的に追加する

    2. SQLite RANDOM()のシード

    3. SQLite Group By

    4. java.sql.SQLException:列数が行1エラーの値数と一致しません