DAY 62 mysql の高度なステートメント

テーブル結合クエリ

MYSQL データベースの 3 種類の接続:

  • 内部結合 (内部結合): 2 つのテーブル内の等しい結合フィールド (交差値を持つ) を持つ行のみを返します。
  • 左結合 (左結合): 左側のテーブルのすべてのレコードと、右側のテーブルの同じ結合フィールドを持つレコードを含むすべてのレコードを返します。
  • 右結合 (右結合): 右側のテーブルのすべてのレコードと、左側のテーブルの同じ結合フィールドを持つレコードを含むすべてのレコードを返します。

注: Oracle データベースは外部結合 (外部結合) をサポートしますが、mysql はサポートしません。

 

左結合 (左結合)

左結合 (左結合): 左側のテーブルのすべてのレコードと、右側のテーブルの同じ結合フィールドを持つレコードを含むすべてのレコードを返します。

 select * from location A LEFT JOIN store_info B on A.store_name=B.store_name;   #左连接

 右結合 (右結合)

右結合 (右結合): 右側のテーブルのすべてのレコードと、左側のテーブルの等しい結合フィールドを持つレコードを含むすべてのレコードを返します。

 select * from location A RIGHT JOIN store_info B on A.store_name=B.store_name;  #右连接

 内部結合 (内部接続)

内部結合 (内部結合): 2 つのテーブル内の結合フィールドが等しい行のみを返します。

方法一:
 select * from location A inner join store_info B on A.store_name=B.store_name;
 ​
 方法二:
 select * from location A, store_info B where A.store_name=B.store_name;
 ​
 方法三:
 select * from location A inner join store_info B using(store_name); #using()是函数,必须保证括号内的字段在两个表中是同名的


 例:

location テーブルの別名を A に設定し、store_info テーブルの別名を B に設定し、テーブル A とテーブル B で同じ store_name フィールド値を持つ行をクエリし、region フィールドをグループ化して集計し、売上の合計を計算します。グループ

select A.region region,sum(B.sales) sales from location A,store_info B where A.store_name=B.store_name group by region;


意見 

ビュー: 仮想テーブルまたはストアド クエリと考えることができます。

  • ビューとテーブルの違いは、テーブルは実際にデータ レコードを格納するのに対し、ビューはテーブル上に構築された構造であり、実際にはデータ レコードを格納しないことです。
  • ユーザーがログアウトするかデータベースへの接続が切断されると、一時テーブルは自動的に消えますが、ビューは消えません。
  • ビューにはデータは含まれず、その定義のみが保存され、一般にビューを使用すると複雑なクエリが簡素化されます。たとえば、複数のテーブルに対して結合クエリを実行し、統計的な並べ替え操作も実行したい場合、SQL ステートメントを記述するのは非常に面倒ですが、ビューを使用して複数のテーブルを結合し、そのビューに対してクエリ操作を実行することは同じです。テーブルに対して操作を実行するのと同じで、クエリと同じで非常に便利です。

文法:

 CREATE VIEW "视图表名" AS "SELECT 语句";   #创建视图表
 ​
 DROP VIEW "视图表名";                     #删除视图表

例:

ビュー表は select ステートメントのクエリ結果であり、select ステートメントの別名として理解できます。

元の表のデータが変更されると、ビュー表の結果も変更されます。

 #将两个表的连接查询,创建为视图表
 create view v_region_sales as select A.region region,sum(B.sales) sales from location A inner join store_info B on A.store_name=B.store_name group by region;
 ​
 select * from v_region_sales;     #查看视图表的存储结果
 ​
 drop view v_region_sales;         #删除视图表

 

 テーブルと派生テーブルの比較を表示する

派生テーブルでは 2 つの選択クエリが 1 つの文に記述されており、より複雑で長くなっています。

テーブルを表示し、複雑なクエリを簡素化します。一度作成するだけで、後から作成したビューテーブルを直接操作できます。

 #派生表:C就是子查询中select语句的派生表。
 select sum(C.sales) from (select A.region region,sum(B.sales) sales from location A,store_info B where A.store_name=B.store_name group by region) C;
 ​
 ​
 #视图表:只需创建一次,后面可以直接对已创建好的视图表进行操作。
 create view v_region_sales as select A.region region,sum(B.sales) sales from location A inner join store_info B on A.store_name=B.store_name group by region;
 ​
 select sum(sales) from v_region_sales;    #对视图表进行操作

ビュー表がデータを挿入できるかどうか

  • ビュー表が2つの表の結合問合せである場合、データは挿入できません。テーブル構造が元のテーブルと矛盾しているためです。
  • ビュー表の構造が元の表の構造と一致している場合は、データを変更および挿入できます。

    • たとえば、元のテーブルにフィールドが 3 つあり、ビューテーブルにフィールドが 2 つある場合、これら 2 つのフィールドが元のテーブルの構造と一致していれば、データを変更および挿入することもできます。(ビューテーブルが単一テーブルに対するクエリの結果である限り)

例1

ビュー表が2つの表の結合問合せである場合、データは挿入できません。テーブル構造が元のテーブルと矛盾しているため

#该视图表是两个表的连接查询
 create view v_region_sales as select A.region region,sum(B.sales) sales from location A inner join store_info B on A.store_name=B.store_name group by region;
 ​
 #查看视图表结构,和原表不一致。
 desc v_region_sales;
 ​
 #插入数据失败
 insert into v_region_sales values('middle',500);


例 2:

ビュー表の構造が元の表の構造と一致している場合は、データを変更および挿入できます。(ビューテーブルが単一テーブルに対するクエリの結果である限り)

#该视图表只是对单个表的查询结果。
 create view v_test_info as select * from store_info;
 ​
 #查看视图表结构,和原表一致。
 desc v_test_info;
 ​
 #插入数据成功
 insert into v_test_info values('NYC',500,'2020-12-10');



連合

UNION: 2 つの SQL ステートメントの結果を結合します。2 つの SQL ステートメントによって生成されるフィールドは同じデータ レコード タイプである必要があります。

UNION (マージ後の重複排除)

結果のデータ レコード値は重複せず、フィールドの順序に従って並べ替えられます。# マージ後の重複排除

 [select 语句1] UNION [select 语句2];
 ​
 示例:
 select store_name from location union select store_name from store_info;
 #将两个表的store_name字段的值合并起来,union生成的结果去重

 交差値

交差値: 2 つの SQL ステートメントの結果の交差値を取得します。

すべて結合 + グループ化 + を使用して交差値を見つけます

注: Union メソッドを使用して交差部分を見つける場合は、2 つのテーブルのターゲット フィールド値を最初に重複排除してからマージする必要があります。単一テーブル内の重複値による計算ミスを回避する

 #两个表各自将store_name字段的值进行去重,之后合并,再创建视图表。
 create view v_store_name as select distinct store_name from location union all select distinct store_name from store_info;
 ​
 #对视图表的store_name字段进行分组汇总,计算每组的数量。
 select store_name,count(*) from v_store_name group by store_name;
 ​
 #对视图表的store_name字段进行分组汇总,计算每组的数量,过滤出数量大于1的store_name字段值,就是两个表的交集部分。
 select store_name from v_store_name group by store_name having count(*) >1;

  内部結合を使用した設定値の交差

 select A.store_name from location A 内部結合 store_info B using(store_name);

2 つのテーブルの store_name フィールド値の共通部分を取得します。

 select A.store_name from location A inner join store_info B on A.store_name=B.store_name;
 ​
 select A.store_name from location A inner join store_info B using(store_name);

 2 つのテーブルの store_name フィールド値の共通部分を取得し、重複を削除して個別の値を追加します。

 select distinct A.store_name from location A inner join store_info B using(store_name);
 #使用左连接查询store_name字段的交集部分
 select * from location A left join store_info B using(store_name);
 ​
 #使用左连接查出store_name字段的交集值,之后去重
 select distinct A.store_name from location A left join store_info B using(store_name) where B.store_name is not null;

 右結合を使用して値を交差する

#使用右连接查出store_name字段的交集值,之后去重
 select distinct A.store_name from location A right join store_info B using(store_name) where A.store_name is not null;
 ​
 #方法二:
 select distinct A.store_name from location A right join store_info B on A.store_name=B.store_name where A.store_name is not null;


 サブクエリを使用して交差値を検索します。


 #使用子查询的方式查出store_name字段的交集值,之后去重
 select distinct store_name from location where store_name in (select store_name from store_info);

 交差値がありません

交差値なし: 2 番目の SQL ステートメントの結果と交差がなく、重複がない最初の SQL ステートメントの結果を表示します。

交差値が見つからない場合は、union all + group by+having を使用します。

 #两个表各自将store_name字段的值进行去重,之后合并,再创建视图表。
 create view v_store_name as select distinct store_name from location union all select distinct store_name from store_info;
 ​
 #对视图表的store_name字段进行分组汇总,计算每组的数量。
 select store_name,count(*) from v_store_name group by store_name;
 ​
 #对视图表的store_name字段进行分组汇总,计算每组的数量,过滤出数量等于1的store_name字段值,就是两个表无交集的部分。
 select store_name from v_store_name group by store_name having count(*) =1;

場合

case: は、IF-THEN-ELSE などのロジックとして SQL で使用されるキーワードです。

文法:

SELECT CASE ("字段 名")
     WHEN "条件1" THEN "结果1"
     WHEN "条件2" THEN "结果2"
     [ELSE "结果N"]
     END
 FROM "表名";
     
 # "条件"可以是一个数值或是公式。ELSE子句则并不是必须的。


例:

 select store_name,CASE store_name        #对sttore_name字段值进行判断
     WHEN 'Los Angeles' THEN sales * 2    #当店名为洛杉矶时销售额乘2
     WHEN 'Boston' THEN 2000              #当店名为波士顿时销售额显示2000
     ELSE sales / 2                       #其他店名则销售额除以2
     END                                  #判断结束
 "new sales", date                        #用于显示的字段名
 from store_info;
 ​
 #"new sales" 是用于case那个字段的字段名。
 ​
 #注:查询并不改变原表的值。

 NULL (NULL) と値なし (' ') の違いNULL (NULL) と値なし (' ') の違い:

  1. 値がない長さは 0 であり、スペースを必要としませんが、NULL 値の長さは NULL で、スペースを必要とします。
  2. IS NULLまたはIS NOT NULL、フィールドが NULL かどうかを判断するために使用され、値がないかどうかを調べることはできません
  3. =' '無価値な判定はまたはを使用して処理されます< >' '<> は等しくないことを表します
  4. 指定したフィールドの行数をカウントするときに count ()、NULL 値が見つかった場合は自動的に無視され、値が見つからなかった場合は計算のためにレコードに追加されます。

正規表現 - 正確なクエリ

一致パターン 説明
^ 一致するテキストの開始文字 '^bd' は bd で始まる文字列と一致します
$ テキストの末尾の文字と一致します 「qn$」は qn で終わる文字列と一致します
任意の 1 文字に一致します 「st」は、s と t の間に 1 文字を含む任意の文字列と一致します。
* 先行する 0 個以上の文字と一致します 'fo*t' は、任意の o が前にある t と一致します。
+ 前の文字と 1 回以上一致します 「hom+」は、ho で始まり、その後に少なくとも 1 つの m が続く文字列と一致します。
指定された文字列と一致します 「clo」は clo を含む文字列と一致します
p1lp2 p1 または p2 に一致します 「bglfg」は bg または fg に一致します
[...] 文字セット内の任意の文字と一致します '[abc]' は a、b、または c に一致します
[^...] 括弧内にない任意の文字と一致します '[^ab]' は、a または b を含まない文字列と一致します。
{n} 前の文字列と n 回一致します 'g{2}' は 2 g を含む文字列と一致します
{n,m} 前の文字列と少なくとも n 回、最大で m 回一致します 'f{1,3}' は f に少なくとも 1 回、最大 3 回一致します

文法:

 select "字段" from "表名" where "字段" regexp {模式};

例:

#查询store_name字段包含字符串"os"的行
 select * from store_info where store_name regexp 'os';
 ​
 #查询store_name字段以A-G开头的行
 select * from store_info where store_name regexp '^[A-G]';
 ​
 #包含Ho或者Bo
 select * from store_info where store_name regexp 'Ho|Bo'; 
 ​
 #以字符串“on”为结尾
 select * from store_info where store_name regexp 'on$';
 ​
 #以“Bo”开头且以“on”为结尾
 select * from store_info where store_name regexp '^Bo.*on$';
 ​
 #查询所有QQ邮箱
 select * from store_info where store_name regexp '.*@qq.com$';`


 

おすすめ

転載: blog.csdn.net/weixin_57560240/article/details/130794905