ホームページ  >  記事  >  データベース  >  MySQL の論理クエリの詳細については、こちらをご覧ください。

MySQL の論理クエリの詳細については、こちらをご覧ください。

青灯夜游
青灯夜游転載
2021-09-17 19:35:522206ブラウズ

クエリは MySQL で最も頻繁に使用される操作であり、DELETE と UPDATE を構築するための基礎でもあります。クエリ処理は論理クエリと物理クエリに分けることができます。今日は論理クエリについて詳しく紹介しますので、お役に立てれば幸いです。

MySQL の論理クエリの詳細については、こちらをご覧ください。

MySQL では、クエリは DELETE と UPDATE を構築するための基礎です。削除または更新する場合は、まずこれらのレコードを見つける必要があるため、SELECT 表示は特に重要です。クエリ処理の場合、論理クエリと物理クエリに分けることができます。論理クエリは、SELECT ステートメントの実行時に生成されるべき結果を示し、物理クエリは、MySQL がこの結果を取得する方法を示します。 [関連する推奨事項: mysql ビデオ チュートリアル ]

この章では、論理クエリについて説明します。

SQL文では、最初にFROM文が処理され、最後にLIMIT文が実行されますが、GROUP BYやORDER BYなど全ての文を使用する場合は、大きく10ステップに分けることができます。以下に示すように、各操作により仮想テーブルが生成されます。

(7) select (8)distinct<select_list>

(1) from <left table>
(3) <join_type> join <right_table>
(2)    on<条件>
(4) where <条件>
(5) group by<字段list>
(6) having<条件>
(9) order by<字段>
(10) limit

実際の例で分析してみましょう。まず、users と order という 2 つのテーブルを作成します。

mysql> create table user (userId int(11),userName varchar(255),city varchar(255), primary key (userId));
Query OK, 0 rows affected, 1 warning (0.05 sec)


mysql> create table orders(orderId int(11) ,userId int(11) ,primary key (orderId));
Query OK, 0 rows affected, 2 warnings (0.05 sec)

データを挿入します。

insert user values(1,"张三","内蒙");
insert user values(2,"李四","内蒙");
insert user values(3,"王五","北京");
insert user values(4,"迪迦","西藏");
insert user values(5,"金甲战士","内蒙");

insert orders values(10001,1);
insert orders values(10002,1);
insert orders values(10003,4);
insert orders values(10004,1);
insert orders values(10005,1);
insert orders values(10006,4);
insert orders values(10007,2);

さて、注文数量が 3 未満の内モンゴルのユーザーをクエリしてみましょう。SQL は次のとおりです。

mysql> select userName,count(orders.orderId) as total from user 
left join orders on user.userId = orders.userId 
where city="内蒙" 
group by user.userId 
having count(orders.orderId)<3 
order by total desc;
+--------------+-------+
| userName     | total |
+--------------+-------+
| 李四         |     1 |
| 金甲战士     |     0 |
+--------------+-------+
2 rows in set (0.00 sec)

データとSQLがあるので、具体的なプロセスを分析してみましょう。

1. デカルト積

#最初に行うことは、FROM ステートメントの前後で 2 つのテーブルのデカルト積を実行することです。 、それではデカルト積とは何でしょうか?たとえば、集合 A={a, b} および集合 B={0, 1, 2} と仮定すると、2 つの集合のデカルト積は {(a, 0), (a, 1), ( a 、2)、(b、0)、(b、1)、(b、2)}。

したがって、上記のデータに対応して、最終的に 35 行のデータを含む仮想テーブル VT1 が生成されます。具体的なデータは次のとおりです。

#1张三内モンゴル1000111张三内モンゴル100021#1张三内モンゴル1000341张三内モンゴル100051##11##1张三内モンゴル100072................黄金の鎧戦士黄金の鎧戦士
userId userName city orderId userId
张三 内モンゴル 10006 1
张三 内モンゴル 10005 4




5
内モンゴル 10001 1 #5
内モンゴル 10002 1

2. ON过滤器

下一步,通过ON后面的添加过滤掉不需要的数据,在上述SQL中,条件是user.userId = orders.userId ,所以通过上面生成的虚拟表VT1,除去不相关的数据,生成新的虚拟表VT2,最终的结果如下。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 张三         | 内蒙   |   10005 |      1 |
|      1 | 张三         | 内蒙   |   10004 |      1 |
|      1 | 张三         | 内蒙   |   10002 |      1 |
|      1 | 张三         | 内蒙   |   10001 |      1 |
|      2 | 李四         | 内蒙   |   10007 |      2 |
|      3 | 王五         | 北京   |    NULL |   NULL |
|      4 | 迪迦         | 西藏   |   10006 |      4 |
|      4 | 迪迦         | 西藏   |   10003 |      4 |
|      5 | 金甲战士     | 内蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

3.添加外部行

这一步只有在连接类型为OUTER JOIN才发生。

LEFT OUTER JOIN把左表记为保留表,RIGHT OUTER JOIN把右表作为保留表,FULL OUTER JOIN表示都作为保留表,添加外部行的工作就是在上一步的基础上添加保留表中被过滤条件过滤掉的数据,非保留表的数据被赋值NULL。

最终生成下面的结果,记为虚拟表VT3。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 张三         | 内蒙   |   10005 |      1 |
|      1 | 张三         | 内蒙   |   10004 |      1 |
|      1 | 张三         | 内蒙   |   10002 |      1 |
|      1 | 张三         | 内蒙   |   10001 |      1 |
|      2 | 李四         | 内蒙   |   10007 |      2 |
|      3 | 王五         | 北京   |    NULL |   NULL |
|      4 | 迪迦         | 西藏   |   10006 |      4 |
|      4 | 迪迦         | 西藏   |   10003 |      4 |
|      5 | 金甲战士     | 内蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

4. WHERE过滤器

这一步很简单,条件为city="内蒙" ,即只保留下city为内蒙的列,并生成新的虚拟表VT4。最终结果如下。

+--------+--------------+--------+---------+--------+
| userId | userName     | city   | orderId | userId |
+--------+--------------+--------+---------+--------+
|      1 | 张三         | 内蒙   |   10005 |      1 |
|      1 | 张三         | 内蒙   |   10004 |      1 |
|      1 | 张三         | 内蒙   |   10002 |      1 |
|      1 | 张三         | 内蒙   |   10001 |      1 |
|      2 | 李四         | 内蒙   |   10007 |      2 |
|      5 | 金甲战士     | 内蒙   |    NULL |   NULL |
+--------+--------------+--------+---------+--------+

5. GROUP BY 分组

这步将上一个步骤进行分组,并生成新的虚拟表VT5,结果如下。

+--------+--------------+--------+
| userId | userName     | city   |
+--------+--------------+--------+
|      1 | 张三         | 内蒙   |
|      2 | 李四         | 内蒙   |
|      5 | 金甲战士     | 内蒙   |
+--------+--------------+--------+

6.HAVING筛选

分完组,我们就可以筛选了,选出count(orders.orderId)<3 的数据即可,最终结果如下。

| userId | userName     | city   | count(orders.orderId) |
+--------+--------------+--------+-----------------------+
|      2 | 李四         | 内蒙   |                     1 |
|      5 | 金甲战士     | 内蒙   |                     0 |
+--------+--------------+--------+-----------------------+

7.处理SELECT列表

虽然SELECT是查询中最先被指定的部分,但是直到这里才真正进行处理,在这一步,将SELECT中指定的列从上一步产生的虚拟表中选出。

8.应用DISTINCT

如果查询语句中存在DISTINCT子句,则会创建一张内存临时表,这张内存临时表的表结构和上一步产生的虚拟表一样,不同的是对进行DISTINCT操作的列增加了一个唯一索引,以此来去除重复数据。

另外对使用了GROUP BY语句的查询,再使用DISTINCT是多余的,因为已经进行了分组,不会移除任何行。

9.排序和LIMIT

最后就是排序,返回新的虚拟表。结果如下。

+--------------+-------+
| userName     | total |
+--------------+-------+
| 李四         |     1 |
| 金甲战士     |     0 |
+--------------+-------+

但是在本例子中没有使用到LIMIT,如果使用到了,那么则从选出指定位置开始的指定行数,

原文地址:https://juejin.cn/post/7000739902937628679

作者:i听风逝夜

更多编程相关知识,请访问:编程视频!!

以上がMySQL の論理クエリの詳細については、こちらをご覧ください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はjuejin.cnで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。