サブクエリ関連

元のテキストへのリンク(この記事は元のテキストの一部ではありません):https://blog.csdn.net/weixin_33331978/article/details/113123563

サブクエリの構文エラーですが、クエリ全体の正確性には影響しません

ユーザーテーブル

id 名前 年齢
1 A 9
2 B 11
3 C 15
4 D 13

ブラックリストテーブル

id 名前 タイプ
1 B 1
2 C 0
3 D 1

エラープロセス

目的:ブラックリストで10歳以上の男性ユーザーのすべての情報を確認します。
正しい文

select * from user where name in (
	select name from blacklist where type = 1
) and age > 10;

エラーステートメント

SELECT * FROM usr WHERE NAME IN (
	SELECT NAME FROM blacklist WHERE TYPE=1 AND age>10
);

年齢条件がクエリ内に追加されますが、ブラックリストに年齢フィールドありません。

サブクエリを単独で実行し、エラーを報告してください!
ここに画像の説明を挿入します
完全なステートメントを実行し、正しい結果を返します
ここに画像の説明を挿入します

問題分析

1、EXPLAIN EXTENDED

EXPLAIN EXTENDED 
SELECT * FROM USER WHERE NAME IN (
	SELECT NAME FROM blacklist WHERE TYPE=1 AND age>10
);

ここに画像の説明を挿入します
2.警告を表示します;
ここに画像の説明を挿入します
3。文を分析します

Field or reference 'test.USER.age' of SELECT #2 was resolved in SELECT #1
select `test`.`user`.`id` AS `id`,`test`.`user`.`name` AS `name`,`test`.`user`.`age` AS `age` 
from `test`.`user` where <in_optimizer>(`test`.`user`.`name`,<exists>(
		select 1 from `test`.`blacklist` where(
		(`test`.`blacklist`.`type` = 1) and (`test`.`user`.`age` > 10) and (<cache>(`test`.`user`.`name`) = `test`.`blacklist`.`name`)
		)
	)
)

簡単に言えば、データベースの最適化後、各フィールドは正しいテーブルを指します。

インタビューの回答:一般的に言って、私は最初にそれを試し、拡張について説明または説明し、次に警告を表示します


記事と比較して、説明した後、警告を表示します;何も起こりません。
だから私はexplainextendedを使用しましたが、私のショーの警告の結果は彼と同じではありません。結果は参加ですが、私のものはそうではありません。

データベースが元のクエリを結合クエリに変更し、各フィールドが正しいテーブルを指していることがわかります。

特定の問題を確認する必要がありますが、バージョンの問題と推定されますか?

inはexistsに置き換えられます

に公開されていない文法エラーがある場合は、に変更して存在し、次のことを試してください。

SELECT * FROM USER WHERE EXISTS (
	SELECT NAME FROM blacklist WHERE TYPE = 1 AND age > 10
);

結果:
ここに画像の説明を挿入します
結果は正しくなく、EXISTSはブール値を返します。サブクエリが行数を返す限り、where条件はtrueです。したがって、選択名を選択1に変更することも当てはまります。つまり、結果は以前と同じになります。

 select * from user where EXISTS (
	 select 1 from blacklist where type = 1 and age > 10
 );

結果は以前と同じです
ここに画像の説明を挿入します

分析

EXPLAIN EXTENDED SELECT * FROM USER WHERE EXISTS (SELECT NAME FROM blacklist WHERE TYPE = 1 AND age > 10);
SHOW WARNINGS; 

結果:

Field or reference 'test.user.age' of SELECT #2 was resolved in SELECT #1
select `test`.`user`.`id` AS `id`,`test`.`user`.`name` AS `name`,`test`.`user`.`age` AS `age` 
	from `test`.`user` where exists(
		select `test`.`blacklist`.`name` from `test`.`blacklist` where (
			(`test`.`blacklist`.`type` = 1) and (`test`.`user`.`age` > 10)
	)
)

存在を使用して、低レベルのエラーも最適化されます。期待するデータを取得したい場合は、existsサブクエリに条件を追加する必要があります

select * from user a where EXISTS (
	select 1 from blacklist where type = 1 and name = a.name and age > 10
);

ここに画像の説明を挿入します

存在はループとして見ることができます

List result = new ArrayList<>();

List user = new ArrayList<>();
for (int i = 0; i < user.size(); i++){
    
    
	if (exists(black.type == 1 && black.name.equals(user.get(i).name)) && user.get(i).age > 10){
    
    
		result.add(user.get(i));
	}
}

NとExistsの違い

存在:最初に外部クエリステートメントを実行し、次にサブクエリを実行します。サブクエリでは、毎回データベースのクエリを実行し、実行回数は外部クエリのデータ数と同じです。

In:最初にin()サブクエリのデータをクエリし(1回)、データをメモリに配置し(複数回クエリする必要はありません)、クエリ結果に従って外部クエリテーブルをクエリしてフィルタリングし、最後に結果を返します。

Inは外部テーブルと内部テーブルの間のハッシュ接続であり、存在するのは外部テーブルのループループであり、ループがループするたびに内部テーブルが照会されます。


総括する

in句の構文エラーは、ステートメント全体の実行に影響を与えない場合があります。

その他

MySQLデータベースにはexplainコマンドがあり、その主な機能はselectステートメントの操作効果を分析することです。たとえば、explainはselectステートメントで使用されるインデックスとソート条件を取得できます。

Explainの拡張拡張機能は、元のExplainに基づいて追加のクエリ最適化情報を提供できます。これは、MySQLのshowwarningsコマンドを介して取得できます。

「MySQLのexplainextendの出力から、SQLがどのように実行されるかを確認できます。これは、SQLの分析に非常に役立ちます。」

おすすめ

転載: blog.csdn.net/root_zhb/article/details/115028656