SQLクエリの実行順序をゼロから学ぶ

SQLクエリの実行順序をゼロから学ぶ

SQL クエリ ステートメントの実行順序は次のとおりです。

(7)選択 
(8) DISTINCT <選択リスト>
(1)<left_table>から
(3)<結合タイプ> JOIN <右テーブル>
(2)ON <結合条件>
(4) WHERE <where_condition>
(5) GROUP BY <group_by_list>
(6) HAVING <having_condition>
(9) ORDER BY <order_by_condition>
(10) LIMIT <制限数>

事前準備

1. 新しいテストデータベースを作成する

データベース testData を作成します。

2. テスト テーブルを作成し、次のようにデータを挿入します。

ユーザーテーブル


注文フォーム


SQL論理クエリテストステートメントを準備する

a.user_id、COUNT(b.order_id) を total_orders として選択します。
ユーザーからの
LEFT JOINはbとして注文する
a.user_id = b.user_id の場合
ここで、a.city = '北京'
GROUP BY a.user_id
COUNT(b.order_id) < 2 である
ORDER BY total_orders desc

上記の SQL クエリを使用して、注文が 2 件未満の北京の顧客を取得します。

これらの SQL ステートメントの実行中に、SQL ステートメントの実行結果を保存するための仮想テーブルが生成されます。

1. FROMステートメントを実行する

最初のステップは、 FROMステートメントを実行することです。まず、どのテーブルから開始するかを知る必要があります。これは、 FROMによってわかります。現在、 <left_table><right_table>という 2 つのテーブルがありますが、どちらのテーブルから始めるべきでしょうか。それとも、2 つのテーブル間に何らかの接続を作成してから始めるべきでしょうか。それらは互いにどのように関係しているのでしょうか? — デカルト積

FROM ステートメントが 2 つのテーブルに対して直積を実行すると、次の内容を持つ仮想テーブル VT1 (仮想テーブル 1) が取得されます。


合計で 28 件 (ユーザーレコード数 * 注文レコード数) のレコードがあります。これは VT1 の結果です。以下の操作は VT1 に基づいています。

2. ONフィルタリングを実行する

デカルト積を実行した後、 ON a.user_id = b.user_id条件フィルタリングが実行されます。 ONで指定された条件に従って、条件を満たさないデータが削除され、次のように VT2 が得られます。

select * from user as a inner JOIN orders as b ON a.user_id = b.user_id; 


3. 外部行を追加する

このステップは、結合タイプがOUTER JOIN ( LEFT OUTER JOINRIGHT OUTER JOINFULL OUTER JOINなど) の場合にのみ実行されます。ほとんどの場合、 OUTERキーワードは省略しますが、 OUTER外部行の概念を表します。

LEFT OUTER JOIN 、左側のテーブルを予約済みテーブルとしてマークします。つまり、左側のテーブルのすべてのデータが照会され、右側のテーブルに対応するデータがない場合、NULL で埋められます。


RIGHT OUTER JOIN 、右側のテーブルを予約済みテーブルとしてマークします。つまり、右側のテーブルのすべてのデータが照会され、左側のテーブルに対応するデータがない場合、NULL が追加されます。


FULL OUTER JOIN左側のテーブルと右側のテーブルの両方を予約済みテーブルとして使用しますが、MySQL は完全結合をサポートしていません。完全結合は次の方法で実装できます。

準備したテスト SQL クエリ ロジック ステートメントで LEFT JOIN を使用したため、結果の VT3 テーブルは次のようになります。


4. where条件フィルタリングを実行する

外部行が追加されたデータは、where 条件によってフィルタリングされます。<where_condition> 条件を満たすレコードのみがフィルタリングされます。次のように WHERE a.city = 'beijing' を実行して VT4 を取得します。


ただし、WHERE 句を使用する場合は、次の 2 つの点に注意する必要があります。

1. データがまだグループ化されていないため、where フィルター条件で where_condition=MIN(col) を使用してグループ統計をフィルターすることはできません。

2. 列選択操作が実行されていないため、選択で列エイリアスを使用することもできません。たとえば、c='beijing' の場合、table1 から city as c を選択することは許可されません。

5. group byステートメントを実行する

GROU BY句は主に、 WHERE句を使用して取得した仮想テーブルをグループ化するために使用されます。次のように GROUP BY a.user_id を実行して VT5 を取得します。


6. 所有の執行

HAVING句は主にGROUP BY句と組み合わせて使用​​され、グループ化によって得られた VT5 のデータに対して条件付きフィルタリングを実行します。次のように HAVING COUNT(b.order_id) < 2 を実行して VT6 を取得します。


7. リストを選択

SELECT句は今のみ実行されます。最初の行に記述されているからといって、 SELECT句が最初に実行される句であると想定しないでください。

テスト ステートメントでSELECT a.user_id,user_name,COUNT(b.order_id) as total_ordersを実行し、VT6 から必要なコンテンツを選択して、次のように VT7 を取得します。


8. 重複データを排除するためにdistinctを実行する

クエリでDISTINCT句が指定されている場合は、一時的なメモリ内テーブルが作成されます (メモリに収まらない場合は、ディスクに保存する必要があります)。この一時テーブルのテーブル構造は、前の手順で生成された仮想テーブルと同じです。違いは、重複データを排除するために、DISTINCT 操作の列に一意のインデックスが追加されていることです。テスト SQL にはDISTINCT句が含まれていないため、実行されません。

9. order by句を実行する

仮想テーブル VT7 の内容を指定された列で並べ替え、新しい仮想テーブルを返します。テスト SQL ステートメントでORDER BY total_orders DESCを実行すると、次の結果が得られます。

DESCは降順で並び替え、ASCは昇順で並び替えます


10. 制限文を実行する

LIMIT 句は、前の手順で取得した仮想テーブルから指定された位置から指定された行データを選択します。これは、ページングによく使用されます。

MySQLデータベースのLIMITは次のオプションをサポートしています: limit n,m

n 番目のレコードから始まる m 個のレコードを選択することを示します。データが小さい場合は、LIMIT 句を使用しても問題ありません。ただし、データ量が非常に多い場合は、LIMIT n, m を使用することは非常に非効率的です。 LIMIT メカニズムは毎回先頭からスキャンするため、600,000 行目から 3 つのデータを読み取る必要がある場合は、最初に 600,000 行目までスキャンしてから読み取る必要があります。スキャン処理は非常に非効率的な処理です。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • PHP で mysqli を使用して複数の SQL クエリ ステートメントを同時に実行する例
  • MySQLクエリ文の実行プロセスを理解するための記事
  • MySQLでSQLクエリ文がどのように実行されるかを分析する
  • Mysql系SQLクエリ文の書き順と実行順を詳しく解説
  • MySQL では SQL クエリはどのように実行されますか?
  • SQLクエリステートメントの実行プロセス

<<:  Dockerイメージの階層化の原理の詳細な説明

>>:  vue プロジェクトで rem を使用して px を置き換える例

推薦する

MySQL でメタデータ ロックがブロックされている場所を確認する方法

MySQL でメタデータ ロックがブロックされている場所を確認する方法手順: 1. セッション1の実...

DockerでSpringbootプロジェクトを実行する方法

1. IDEAの下にあるターミナルをクリックし、mvn clean installと入力します。 次...

Vueを使用して手書き署名機能を実装する

個人的な実装のスクリーンショット:インストール: npm インストール vue-esign --sa...

MySQL 8.0.11 の新機能の紹介

MySQL 8.0 for Windows v8.0.11 公式無料バージョン 64 ビット1. デ...

CSS の画像パスの問題に関する議論 (同じパッケージ/異なるパッケージ)

CSS ファイルでは、背景を使用する、つまり背景画像を追加する必要がある場合があります。これは通常、...

シンプルな虫眼鏡効果を実現するJavaScript

大きな箱の中に写真があります。マウスをその上に置くと、半透明のマスク レイヤーが表示されます。マウス...

seata docker 高可用性デプロイメントの詳細な紹介

バージョン1.4.2公式ドキュメントドッカーハブ起動する環境変数SEATA_CONFIG_NAMEを...

Docker で最初のアプリケーションをデプロイする方法

前回の記事では、Docker Desktop をインストールし、Kubernetes を有効にしまし...

Vue.jsは背景テーブルコンポーネントのカプセル化を管理します

目次問題分析なぜカプセル化なのかパッケージの内容は何ですか?テーブルコンポーネントをカプセル化するデ...

高同時実行シナリオにおける nginx 最適化の詳細な説明

日常の運用・保守作業では、nginx サービスが頻繁に使用され、nginx の高同時実行性によって生...

リモートホスト上でスクリプトや命令を実行する Zabbix の詳細な説明

シナリオ要件1. zabbix_server Web インターフェースのスクリプト機能を使用すると、...

HTTP ヘッダー情報の解釈と分析 (詳細概要)

HTTP ヘッダーの説明1. Accept: Web サーバーに受け入れるメディア タイプを通知しま...

Nginx ローカル ディレクトリ マッピング実装コード例

他のデバイスの画像をローカルディレクトリにマウントするなど、サーバー上の静的リソースにアクセスする必...

Vueはプルダウンを実装してさらに読み込む

Element-UI に慣れた開発者なら、無限スクロールの InfiniteScroll が使いにく...

Vue Routerはバックグラウンドデータに応じて異なるコンポーネントをロードします

目次実際のプロジェクトで遭遇する要件実装が間違っているところもある私は個人的に、実装するより良い方法...