クエリは MySQL で最も頻繁に使用される操作であり、DELETE と UPDATE を構築するための基礎でもあります。クエリ処理は論理クエリと物理クエリに分けることができます。今日は論理クエリについて詳しく紹介しますので、お役に立てれば幸いです。
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 が生成されます。具体的なデータは次のとおりです。
userId | userName | city | orderId | userId |
---|---|---|---|---|
张三 | 内モンゴル | 10001 | 1 | |
张三 | 内モンゴル | 10002 | 1 | |
张三 | 内モンゴル | 10003 | 4 | |
张三 | 内モンゴル | 10005 | 1 | |
张三 | 内モンゴル | 10006 | 1 | |
张三 | 内モンゴル | 10005 | 4 | ##1 |
内モンゴル | 10007 | 2 | ................ | |
5 |
||||
内モンゴル | 10001 | 1 | #5 | |
内モンゴル | 10002 | 1 |
2. ON过滤器 下一步,通过ON后面的添加过滤掉不需要的数据,在上述SQL中,条件是 +--------+--------------+--------+---------+--------+ | 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过滤器 这一步很简单,条件为 +--------+--------------+--------+---------+--------+ | 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筛选 分完组,我们就可以筛选了,选出 | 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,如果使用到了,那么则从选出指定位置开始的指定行数,
更多编程相关知识,请访问:编程视频!! |
以上がMySQL の論理クエリの詳細については、こちらをご覧ください。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。