元のテキストへのリンク(この記事は元のテキストの一部ではありません):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の分析に非常に役立ちます。」