MYSQL文のSELECT文とその句の実行順序

2758 ワード

SELECT文の実行の論理クエリー処理手順:(8)SELECT(9)DISTINCT(11)(1)FROM(3)JOIN(2)ON(4)WHERE(5)GROUP BY(6)WITH{CUBE|ROLLUP}(7)HAVING(10)ORDER BY
1.FROM2.ON3.JOIN4.WHERE5.GROUP BY6.WITH CUBE or WITH ROLLUP7.HAVING8.SELECT9.DISTINCT10.ORDER BY11.TOP
MICROSOFTは,SELECT文の実際の物理的実行順序がクエリプロセッサによってこの順序と異なる可能性があると指摘している.
各ステップは、次のステップの入力として使用される仮想テーブルを生成します.最後のステップで生成されたテーブルのみが呼び出し元に返されます.句がない場合は、対応する手順をスキップします.1.FROM:FROM句の最初の2つのテーブルにデカルト積を実行し、仮想テーブルVT 1を生成する.2.ON:VT 1にONフィルタを適用する.VT 2が挿入されるのは、実際の行としてのみです.3.OUTER(JOIN):OUTER JOINが指定されている場合、保留表に一致しない行が外部行としてVT 2に追加され、VT 3が生成されます.FROM句に2つ以上のテーブルが含まれている場合、前の結合で生成された結果テーブルと次のテーブルについて、すべてのテーブルが処理されるまで手順1~3を繰り返します.4.VT 3に対してWHEREフィルタを適用する.VT 4は、TRUEとしての行のみ挿入される.5.GROUP BY:GROUUPBY句の列リストからVT 4の行をグループ化し、VT 5を生成する.6.CUBE|ROLLUP:スーパーグループをVT 5に挿入し、VT 6を生成する.7.HAVING:VT 6にHAVINGフィルタを適用します.VT 7はTRUEとしてのグループのみ挿入される.8.SELECT:SELECTリストを処理し、VT 8を生成する.9.DISTINCT:重複する行をVT 8から除去し、VT 9を生成する.10.ORDER BY:VT 9の行をORDER BY句の列リストで並べ替え、テーブル(VC 10)を生成します.11.TOP:VC 10の先頭から指定された数または割合の行を選択し、テーブルVT 11を生成し、呼び出し元に返す.
 
例1:

     SELECT ID,COUNT(ID) AS TOTAL 
    

FROM STUDENT

GROUP BY ID

HAVING TOTAL>2

 
このSQL文は見覚えがあると思いますか?はい、非常に基礎的なグループクエリーです.しかし、HAVINGの実行順序がSELECTの上にあるため、成功することはできません.
実際の実行順序は次のとおりです.
1.FROM STUDENT2.GROUP BY ID3.HAVING TOTAL>24.SELECT ID,COUNT(ID)AS TOTALは明らかで,TOTALは最後のSELECT ID,COUNT(ID)AS TOTAL実行後に生成された新しい別名である.このため、HAVING TOTAL>2の実行時にTOTALを認識することはできない.
例2
 
    
SELECT ID,COUNT(ID) AS TOTAL

FROM STUDENT

GROUP BY ID

ORDER BY TOTAL

 
この実際の実行順序は次のとおりです.
1.FROM STUDENT2.GROUP BY ID3.SELECT ID,COUNT(ID) AS TOTAL4.ORDER BY TOTALは今回は何の問題もなく、実行に成功しました.ORDER BY TOTALをORDER BY COUNT(ID)に変えたら?
 
    
SELECT ID,COUNT(ID) AS TOTAL

FROM STUDENT

GROUP BY ID

ORDER BY COUNT(ID)

実際の実行順序:
 
1.FROM STUDENT2.GROUP BY ID3.SELECT ID,COUNT(ID) AS TOTAL4.ORDER BY COUNT(ID)
そう、それは成功して実行することができて、SQLの実行計画を見て、それは上のORDER BY TOTALと同じです.ORDER BYはSELECT後に実行されるため、別名TOTALを用いることができる.
例3
 
    
SELECT FIRSTNAME+' '+LASTNAME AS NAME, COUNT(*) AS COUNT

FROM STUDENT

GROUP BY NAME

 
実際の実行順序:
 
    
FROM STUDENT

GROUP BY NAME

SELECT FIRSTNAME+' '+LASTNAME AS NAME,COUNT(*) AS COUNT

 
GROUP BY NAMEの実行時に別名NAMEが作成されていないことは明らかであり、成功することはできない.
転載先:https://www.cnblogs.com/ShanHeDiao/p/4374257.html