MySQL で結合を使用して SQL を最適化する方法の詳細な説明

MySQL で結合を使用して SQL を最適化する方法の詳細な説明

0. 以下のテストに関連する表を準備する

関連するテーブル作成ステートメントについては、https://github.com/YangBaohust/my_sql を参照してください。

User1 テーブル、学習グループ +----+-----------+-----------------+---------------------------------+
| id | ユーザー名 | コメント | モバイル |
+----+-----------+-----------------+---------------------------------+
| 1 | 唐僧 | 白檀功徳仏 | 138245623,021-382349 |
| 2 | 孫悟空 | 戦う仏陀 | 159384292,022-483432,+86-392432 |
| 3 | 朱八戒 | 祭壇洗浄剤 | 183208243,055-8234234 |
| 4 | 沙僧 | 金体羅漢 | 293842295,098-2383429 |
| 5 | NULL | ホワイトドラゴンホース | 993267899 |
+----+-----------+-----------------+---------------------------------+

ユーザー2 テーブル、悟空の友達の輪 +----+--------------+-----------+
| ID | ユーザー名 | コメント |
+----+--------------+-----------+
| 1 | 孫悟空 | 孫悟空 |
| 2 | 牛魔王 | 牛兄さん |
| 3 | 鉄扇公主 | 牛夫人 |
| 4 | 菩提祖師 | ブドウ |
| 5 | NULL | ジンジン|
+----+--------------+-----------+

user1_kills テーブル、西への旅で倒したモンスターの数 +----+-----------+----------------------+-------+
| id | user_name | timestr | キル |
+----+-----------+----------------------+-------+
| 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 |
| 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 |
| 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 |
| 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 5 | 朱八傑 | 2013-01-11 00:00:00 | 20 |
| 6 | 朱八傑 | 2013-02-07 00:00:00 | 17 |
| 7 | 朱八傑 | 2013-02-08 00:00:00 | 35 |
| 8 | シャ・セン | 2013-01-10 00:00:00 | 3 |
| 9 | シャ・セン | 2013-01-22 00:00:00 | 9 |
| 10 | 沙生 | 2013-02-11 00:00:00 | 5 |
+----+-----------+----------------------+-------+

user1_equipment テーブル、クエスト グループ装備 +----+-----------+--------------+-----------------+-----------------+
| id | ユーザー名 | 武器 | 衣類 | 靴 |
+----+-----------+--------------+-----------------+-----------------+
| 1 | 唐僧| 九輪の杖| カラフルなカソック| 僧侶の靴|
| 2 | 孫悟空| 黄金の棍棒| 黄金の鎧| 蓮華絹雲靴|
| 3 | 朱八戒| 九歯の熊手| 僧衣| 僧靴|
| 4 | 沙僧侶| 悪魔鎮圧杖| 僧侶のローブ| 僧侶の靴|
+----+-----------+--------------+-----------------+-----------------+

1. 左結合を使用してnot in句を最適化する

例: 巡礼グループの中で悟空の友人ではない人を見つける

+----+-----------+-----------------+------------------------+
| id | ユーザー名 | コメント | モバイル |
+----+-----------+-----------------+------------------------+
| 1 | 唐僧 | 白檀功徳仏 | 138245623,021-382349 |
| 3 | 朱八戒 | 祭壇洗浄剤 | 183208243,055-8234234 |
| 4 | 沙僧 | 金体羅漢 | 293842295,098-2383429 |
+----+-----------+-----------------+------------------------+

書面ではない場合:

user1 a から * を選択します。ここで、a.user_name は存在しません (user_name が null でない user2 から user_name を選択します)。

左結合の書き方:

まず、user_nameで接続された外部結合データセットを見てみましょう。

user1 a から a.*、b.* を選択し、user2 b を (a.user_name = b.user_name) に結合します。
+----+-----------+-----------------+---------------------------------+-------+-----------+-----------+
| id | ユーザー名 | コメント | モバイル | id | ユーザー名 | コメント |
+----+-----------+-----------------+---------------------------------+-------+-----------+-----------+
| 2 | 孫悟空 | 戦う仏陀 | 159384292,022-483432,+86-392432 | 1 | 孫悟空 | 孫悟空 |
| 1 | 唐僧 | 白檀功徳仏 | 138245623,021-382349 | NULL | NULL | NULL |
| 3 | 朱八戒 | 祭壇洗浄剤 | 183208243,055-8234234 | NULL | NULL | NULL |
| 4 | 沙僧 | 金体阿羅漢 | 293842295,098-2383429 | NULL | NULL | NULL |
| 5 | NULL | ホワイトドラゴンホース | 993267899 | NULL | NULL | NULL |
+----+-----------+-----------------+---------------------------------+-------+-----------+-----------+

テーブル a のすべてのデータが表示され、テーブル b のデータは b.user_name が a.user_name と等しい場合にのみ表示され、残りは null 値で埋められていることがわかります。西遊記に登場する悟空の友人ではない人物を見つけるには、b.user_name が b.user_name で null であるというフィルター条件を追加するだけです。

user1 a left から a.* を選択し、user2 b on (a.user_name = b.user_name) を結合します。ここで、b.user_name は null です。
+----+-----------+-----------------+------------------------+
| id | ユーザー名 | コメント | モバイル |
+----+-----------+-----------------+------------------------+
| 1 | 唐僧 | 白檀功徳仏 | 138245623,021-382349 |
| 3 | 朱八戒 | 祭壇洗浄剤 | 183208243,055-8234234 |
| 4 | 沙僧 | 金体羅漢 | 293842295,098-2383429 |
| 5 | NULL | ホワイトドラゴンホース | 993267899 |
+----+-----------+-----------------+------------------------+

ここで、結果セットにもう 1 頭の白いドラゴン ホースがあることがわかるので、フィルター条件 a.user_name is not null を追加し続けることができます。

user1 a left join user2 b on (a.user_name = b.user_name) から a.* を選択します。ここで、b.user_name は null であり、a.user_name は null ではありません。

2. 左結合を使用してスカラーサブクエリを最適化する

例: 悟空の友達サークルの西遊記グループの人々のニックネームを確認する

+-----------+-----------------+-----------+
| ユーザー名 | コメント | コメント2 |
+-----------+-----------------+-----------+
| 唐僧 | 白檀功徳仏 | NULL |
| 孫悟空| 戦う仏陀| 孫悟空|
| 朱八戒| 祭壇洗浄剤| NULL |
| 沙僧侶 | 金体阿羅漢 | NULL |
| NULL | ホワイトドラゴンホース | NULL |
+-----------+-----------------+-----------+

サブクエリの記述:

a.user_name、a.comment、(b.user_name = a.user_name の場合、user2 b から comment を選択)、user1 a から comment2 を選択します。

左結合の書き方:

user1 a から a.user_name、a.comment、b.comment comment2 を選択し、user2 b を (a.user_name = b.user_name) で結合します。

3. 結合を使用して集計サブクエリを最適化する

例: 巡礼団の各メンバーが最も多くのモンスターを倒した日付を見つける

+----+-----------+----------------------+-------+
| id | user_name | timestr | キル |
+----+-----------+----------------------+-------+
| 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 7 | 朱八傑 | 2013-02-08 00:00:00 | 35 |
| 9 | シャ・セン | 2013-01-22 00:00:00 | 9 |
+----+-----------+----------------------+-------+

集計サブクエリの記述方法:

user1_kills a から * を選択します。ここで、a.kills = (user1_kills b から max(b.kills) を選択します。ここで、b.user_name = a.user_name);

結合書き込み方法:

まず、2 つのテーブルの自己関連付けの結果セットを見てみましょう。スペースを節約するために、Zhu Bajie のモンスター退治データのみを取り上げます。

user1_kills a から a.*、b.* を選択し、user1_kills b を (a.user_name = b.user_name) で結合して、順序を 1 にします。
+----+-----------+---------------------+-------+----+----------+----------------------+-------+
| id | user_name | timestr | kills | id | user_name | timestr | kills |
+----+-----------+---------------------+-------+----+----------+----------------------+-------+
| 5 | 朱八傑 | 2013-01-11 00:00:00 | 20 | 5 | 朱八傑 | 2013-01-11 00:00:00 | 20 |
| 5 | 朱八戒 | 2013-01-11 00:00:00 | 20 | 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 |
| 5 | 朱八戒 | 2013-01-11 00:00:00 | 20 | 7 | 朱八戒 | 2013-02-08 00:00:00 | 35 |
| 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 | 7 | 朱八戒 | 2013-02-08 00:00:00 | 35 |
| 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 | 5 | 朱八戒 | 2013-01-11 00:00:00 | 20 |
| 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 | 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 |
| 7 | 朱八戒 | 2013-02-08 00:00:00 | 35 | 5 | 朱八戒 | 2013-01-11 00:00:00 | 20 |
| 7 | 朱八戒 | 2013-02-08 00:00:00 | 35 | 6 | 朱八戒 | 2013-02-07 00:00:00 | 17 |
| 7 | 朱八傑 | 2013-02-08 00:00:00 | 35 | 7 | 朱八傑 | 2013-02-08 00:00:00 | 35 |
+----+-----------+---------------------+-------+----+----------+----------------------+-------+

2 つのテーブルが user_name を介して自己関連付けられている場合、テーブル a のすべてのフィールドに対して group by を実行し、テーブル b で max(kills) を取得するだけでよいことがわかります。a.kills=max(b.kills) である限り、要件は満たされます。 SQLは次のとおりです

user1_kills から a.* を選択し、 user1_kills b を (a.user_name = b.user_name) で結合し、 a.id、a.user_name、a.timestr、a.kills でグループ化します。 a.kills = max(b.kills);

4. グループ選択に結合を使用する

例: 3番目の例をアップグレードして、巡礼グループの各人が最も多くのモンスターを倒した最初の2つの日付を見つけます。

+----+-----------+----------------------+-------+
| id | user_name | timestr | キル |
+----+-----------+----------------------+-------+
| 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 |
| 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 5 | 朱八傑 | 2013-01-11 00:00:00 | 20 |
| 7 | 朱八傑 | 2013-02-08 00:00:00 | 35 |
| 9 | シャ・セン | 2013-01-22 00:00:00 | 9 |
| 10 | 沙生 | 2013-02-11 00:00:00 | 5 |
+----+-----------+----------------------+-------+

Oracleでは、分析関数を通じてこれを実現できます。

(select a.*, row_number() over(partition by user_name order by kills desc) cnt from user1_kills a) b から b.* を選択します。ここで、b.cnt <= 2 です。

残念ながら、上記の SQL は MySQL でエラーを報告します: ERROR 1064 (42000): SQL 構文にエラーがあります。MySQL は分析関数をサポートしていないためです。ただし、次の方法で実現できます。

まず、2 つのテーブルは自己関連付けられています。スペースを節約するために、Sun Wukong のデータのみが取り出されます。

user1_kills a から a.*、b.* を選択し、user1_kills b を (a.user_name=b.user_name かつ a.kills<=b.kills) で結合し、a.user_name、a.kills で並べ替えます。
+----+-----------+---------------------+-------+----+----------+----------------------+-------+
| id | user_name | timestr | kills | id | user_name | timestr | kills |
+----+-----------+---------------------+-------+----+----------+----------------------+-------+
| 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 | 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 | 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 |
| 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 | 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 | 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 |
| 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 | 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 |
| 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 | 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 | 1 | 孫悟空 | 2013-01-10 00:00:00 | 10 |
| 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 | 3 | 孫悟空 | 2013-02-05 00:00:00 | 12 |
| 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 | 4 | 孫悟空 | 2013-02-12 00:00:00 | 22 |
| 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 | 2 | 孫悟空 | 2013-02-01 00:00:00 | 2 |
+----+-----------+---------------------+-------+----+----------+----------------------+-------+

上記の表から、孫悟空が倒したモンスターの数は 22 と 12 であることがわかります。次に、テーブル a のすべてのフィールドでグループ化を実行し、テーブル b の ID をカウントするだけです。カウント値が 2 以下の場合、要件は満たされます。SQL は次のように書き換えられます。

user1_kills a から a.* を選択し、user1_kills b を (a.user_name=b.user_name かつ a.kills<=b.kills) で結合し、a.id、a.user_name、a.timestr、a.kills でグループ化し、count(b.id) <= 2 を持ちます。

5. 直積結合を使用して1つの列を複数の行に変換する

例: クエリグループ内の各電話番号を行に変換する

元データ:

+-----------+---------------------------------+
| ユーザー名 | モバイル |
+-----------+---------------------------------+
| 唐僧侶 | 138245623,021-382349 |
| 孫悟空 | 159384292,022-483432,+86-392432 |
| 朱八傑 | 183208243,055-8234234 |
| シャ・セン | 293842295,098-2383429 |
| NULL | 993267899 |
+-----------+---------------------------------+

取得したいデータ:

+-----------+--------------+
| ユーザー名 | モバイル |
+-----------+--------------+
| 唐僧 | 138245623 |
| タンモンク | 021-382349 |
| 孫悟空 | 159384292 |
| 孫悟空 | 022-483432 |
| 孫悟空 | +86-392432 |
| 朱八戒 | 183208243 |
| 朱八傑 | 055-8234234 |
| シャ・セン | 293842295 |
| 沙生 | 098-2383429 |
| NULL | 993267899 |
+-----------+--------------+

Tang Seng さんは電話を 2 台持っているので、回線が 2 本必要だということがわかります。まず各人の電話番号の数を調べ、次にシーケンステーブルとの直積を実行します。スペースを節約するために、Tang Sengのデータのみが取り出されます。

tb_sequence から a.id、b.* を選択します。a クロス結合 (user_name、mobile、length(mobile)-length(replace(mobile、','、''))+1 size を user1 から選択します) b 2,1 で順序付けします。
+----+-----------+---------------------------------+------+
| ID | ユーザー名 | モバイル | サイズ |
+----+-----------+---------------------------------+------+
| 1 | 唐僧 | 138245623,021-382349 | 2 |
| 2 | 唐僧 | 138245623,021-382349 | 2 |
| 3 | 唐僧 | 138245623,021-382349 | 2 |
| 4 | 唐僧 | 138245623,021-382349 | 2 |
| 5 | 唐僧 | 138245623,021-382349 | 2 |
| 6 | 唐僧 | 138245623,021-382349 | 2 |
| 7 | 唐僧 | 138245623,021-382349 | 2 |
| 8 | 唐僧 | 138245623,021-382349 | 2 |
| 9 | 唐僧 | 138245623,021-382349 | 2 |
| 10 | 唐僧 | 138245623,021-382349 | 2 |
+----+-----------+---------------------------------+------+

a.id は電話番号の数に対応し、size は電話番号の合計数です。したがって、相関条件 (a.id <= b.size) を追加して、上記の SQL ステートメントを調整できます。

tb_sequence から b.user_name、replace(substring(substring_index(b.mobile, ',', a.id), char_length(substring_index(mobile, ',', a.id-1)) + 1)、','、'') を mobile として選択し、cross join (select user_name、concat(mobile, ',') as mobile、length(mobile)-length(replace(mobile, ',', ''))+1 size from user1) b on (a.id <= b.size);

6. 直積結合を使用して複数の列を複数の行に変換する

例: クエストグループ内の各装備を一列に並べる

元データ:

+----+-----------+--------------+-----------------+-----------------+
| id | ユーザー名 | 武器 | 衣類 | 靴 |
+----+-----------+--------------+-----------------+-----------------+
| 1 | 唐僧| 九輪の杖| カラフルなカソック| 僧侶の靴|
| 2 | 孫悟空| 黄金の棍棒| 黄金の鎧| 蓮華絹雲靴|
| 3 | 朱八戒| 九歯の熊手| 僧衣| 僧靴|
| 4 | 沙僧侶| 悪魔鎮圧杖| 僧侶のローブ| 僧侶の靴|
+----+-----------+--------------+-----------------+-----------------+

取得したいデータ:

+-----------+----------+-----------------+
| ユーザー名 | 装備 | 装備豆 |
+-----------+----------+-----------------+
| 唐僧 | 武器 | 九輪の杖 |
| 唐僧 | 衣服 | カラフルなカソック |
| 唐僧 | 靴 | 僧侶の靴 |
| 孫悟空| 武器 | 黄金の棍棒|
| 孫悟空| 衣服 | シャトルゴールデンアーマー|
| 孫悟空 | 靴 | 蓮の絹雲靴 |
| 沙生| 武器 | 魔を鎮める杖|
| 沙僧| 衣服 | 僧侶の衣服|
| 沙生| 靴 | 僧侶の靴|
| 朱八戒| 武器 | 九歯の熊手|
| 朱八戒| 衣服 | 僧侶の衣服|
| 朱八戒| 靴 | 僧侶の靴|
+-----------+----------+-----------------+

union の書き方:

user_name、装備として「arms」、user1_equipment からarms equip_mame を選択します。
すべて結合
user_name、装備として「clothing」、user1_equipment からclothing equip_mame を選択します
すべて結合
user_name、装備として「shoe」、user1_equipment から靴 equip_mame を選択します
1、2 の順に並べます。

join の書き方:

まず、デカルトデータセットの効果を、タン・センを例に見てみましょう。

user1_equipment a から a.*、b.* を選択します。b.id <= 3 の場合、tb_sequence b をクロス結合します。
+----+-----------+--------------+-----------------+-----------------+----+
| id | ユーザー名 | 武器 | 衣類 | 靴 | id |
+----+-----------+--------------+-----------------+-----------------+----+
| 1 | 唐僧| 九輪の杖| カラフルなカソック| 僧侶の靴| 1 |
| 1 | 唐僧 | 九輪の杖 | カラフルなカソック | 僧侶の靴 | 2 |
| 1 | 唐僧 | 九輪の杖 | カラフルなカソック | 僧侶の靴 | 3 |
+----+-----------+--------------+-----------------+-----------------+----+

上記の結果を処理するユースケース

ユーザー名を選択、 
b.id = 1 の場合、「arms」 
b.id = 2 の場合、「clothing」
b.id = 3 の場合、「shoe」は装備として終了します。
b.id = 1 の場合、arms は終了し、
b.id = 2 の場合、clothing はclothing を終了します。
b.id = 3 の場合、shoe 終了shoe
user1_equipment a から、b.id <=3 の tb_sequence b をクロス結合します。
+-----------+----------+--------------+-----------------+-----------------+
| ユーザー名 | 装備 | 武器 | 衣類 | 靴 |
+-----------+----------+--------------+-----------------+-----------------+
| 唐僧 | 武器 | 九輪の杖 | NULL | NULL |
| 唐僧 | 衣服 | NULL | カラフルなカソック | NULL |
| 唐僧 | 靴 | NULL | NULL | 僧侶の靴 |
+-----------+----------+--------------+-----------------+-----------------+

coalesce関数を使用して複数のデータ列を結合する

ユーザー名を選択、 
b.id = 1 の場合、「arms」 
b.id = 2 の場合、「clothing」
b.id = 3 の場合、「shoe」は装備として終了します。
合体(b.id = 1の場合、armsは終了、
b.id = 2 の場合、衣服は終了です。
b.id = 3 の場合、シュー終了) equip_mame
user1_equipment a から、b.id <=3 の tb_sequence b をクロス結合し、1、2 で順序付けします。

7. 結合を使用して、フィルター条件に自分自身を含むテーブルを更新します。

例: 西遊記グループと悟空の友達サークルの両方に所属している人の場合、西遊記グループのコメント欄を「この人は悟空の友達サークルに所属しています」に更新します。

まずuser_nameがuser1とuser2の両方に存在する人を見つけ、次にuser1テーブルを更新するのが自然です。SQLは次のようになります。

user1 を更新し、comment を 'この人は Wukong の友達サークルにいます' に設定し、user_name を (select a.user_name from user1 a join user2 b on (a.user_name = b.user_name));

残念ながら、上記の SQL は MySQL でエラーを報告します: ERROR 1093 (HY000): FROM 句で更新のターゲット テーブル 'user1' を指定することはできません。これは、FROM 句のターゲット テーブルを更新できないことを示しています。

他に方法はあるでしょうか? in メソッドを join メソッドに変換できます。

user1 から c.*、d.* を選択します c join (user1 から a.user_name を選択し、a join user2 b on (a.user_name = b.user_name)) d on (c.user_name = d.user_name);
+----+-----------+--------------+-------------------------------------------+
| id | ユーザー名 | コメント | モバイル | ユーザー名 |
+----+-----------+--------------+-------------------------------------------+
| 2 | 孫悟空 | 戦う仏陀 | 159384292,022-483432,+86-392432 | 孫悟空 |
+----+-----------+--------------+-------------------------------------------+

結合後にビューを更新します

user1 を更新 c join (user1 から a.user_name を選択 a join user2 b on (a.user_name = b.user_name)) d on (c.user_name = d.user_name) c.comment を 'この人は Wukong の友達サークルにいます' に設定;

もう一度user1を確認すると、user1が正常に変更されたことがわかります。

user1 から * を選択します。
+----+-----------+----------------------------+---------------------------------+
| id | ユーザー名 | コメント | モバイル |
+----+-----------+----------------------------+---------------------------------+
| 1 | 唐僧 | 白檀功徳仏 | 138245623,021-382349 |
| 2 | 孫悟空 | この人物は孫悟空の友人の輪の中にいます | 159384292,022-483432,+86-392432 |
| 3 | 朱八戒 | 祭壇洗浄剤 | 183208243,055-8234234 |
| 4 | 沙僧 | 金体羅漢 | 293842295,098-2383429 |
| 5 | NULL | ホワイトドラゴンホース | 993267899 |
+----+-----------+----------------------------+---------------------------------+

8. 結合を使用して重複データを削除する

まず、user2テーブルに2つのデータを挿入します

insert into user2(user_name, comment) values ​​('孙悟空', '美猴王');
user2(user_name, comment) に values ​​('牛魔王', '牛哥') を挿入します。

例: user2 テーブル内の重複データを削除し、ID 番号が大きいデータのみを保持する

+----+--------------+-----------+
| ID | ユーザー名 | コメント |
+----+--------------+-----------+
| 1 | 孫悟空 | 孫悟空 |
| 2 | 牛魔王 | 牛兄さん |
| 3 | 鉄扇公主 | 牛夫人 |
| 4 | 菩提祖師 | ブドウ |
| 5 | NULL | ジンジン|
| 6 | 孫悟空 | 孫悟空 |
| 7 | 牛魔王 | 牛兄さん |
+----+--------------+-----------+

まず重複レコードをチェックする

user2 から a.*、b.* を選択します。a は、user2 から user_name、comment、max(id) id を選択して、user_name、comment で count(*) > 1 を持つグループを作成します。b は、(a.user_name=b.user_name かつ a.comment=b.comment) で、order by 2 になります。
+----+------------+------------+-----------+---------+------+
| id | ユーザー名 | コメント | ユーザー名 | コメント | id |
+----+------------+------------+-----------+---------+------+
| 1 | 孫悟空| 孫悟空| 孫悟空| 6 |
| 6 | 孫悟空| 孫悟空| 孫悟空| 孫悟空| 6 |
| 2 | 牛魔王| 牛兄| 牛魔王| 牛兄| 7 |
| 7 | 牛魔王| 牛兄| 牛魔王| 牛兄| 7 |
+----+------------+------------+-----------+---------+------+

次に、(a.id < b.id) のデータを削除します。

user2 から a を削除 a join (select user_name, comment, max(id) id from user2 group by user_name, comment having count(*) > 1) b on (a.user_name=b.user_name and a.comment=b.comment) where a.id < b.id;

user2を確認すると、重複データが削除されていることがわかります。

user2 から * を選択します。
+----+--------------+-----------+
| ID | ユーザー名 | コメント |
+----+--------------+-----------+
| 3 | 鉄扇公主 | 牛夫人 |
| 4 | 菩提祖師 | ブドウ |
| 5 | NULL | ジンジン|
| 6 | 孫悟空 | 孫悟空 |
| 7 | 牛魔王 | 牛兄さん |
+----+--------------+-----------+

要約:

私が言いたいのはこれだけです。興味があれば、さらにデータを作成し、さまざまな SQL ステートメントの実行時間を比較することができます。この記事の例は、MOOC.com のコース「SQL 開発スキル」から抜粋したものです。

さて、今回の記事は以上です。この記事の内容が皆さんの勉強や仕事に少しでも参考になれば幸いです。123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL 結合テーブルクエリの基本操作 左結合のよくある落とし穴
  • MySQL の on と where における左結合設定条件の使用法の違いの分析
  • MySQL におけるさまざまな一般的な結合テーブルクエリの例の概要
  • MySQL 8.0.18 ハッシュ結合は左/右結合をサポートしていません 左と右の結合の問題
  • Mysql 8.0.18 ハッシュ結合テスト (推奨)
  • MySQL 8.0 の新機能: ハッシュ結合
  • MySQL 8.0.18 安定版がリリースされました! 予想通りハッシュ結合が実装されました
  • MySQLにおける(JOIN/ORDER BY)文のクエリ処理と最適化方法
  • MySQLの自己接続と結合の詳細な理解
  • MySQL 結合テーブルと ID 自動増分の例の分析

<<:  jQueryは検証コード送信のコントロールボタンを無効にする機能を実装します

>>:  Dockerボリュームコンテナ間のデータ共有の実装

推薦する

CSS 兄弟要素フローティング分析の概要

float:左/右/なし; 1. 同じレベルフローティング(1)ブロックレベル要素を同じ行に表示する...

JavaScript の差異を利用して比較ツールを実装する

序文仕事では、毎週従業員が提出した資料を数える必要がありますが、それを一つずつコピーして貼り付けるの...

wavesurfer.js によるオーディオ波形描画の実装

1. レンダリングを見る進むを選択: 後方を選択: コードは次のとおりです(例): <テンプレ...

JavaScript インタビュー: 配列の平坦化メソッドを実装する方法

目次1 配列のフラット化とは何ですか? 2 JS標準ライブラリの配列フラット化メソッド3 フラットメ...

良いと思う国内のデザインサイトをいくつか選んでみました。

<br />私が良いと思った国内のデザインサイトをまとめてみました。広告ではありません!...

Intelli Idea で Tomcat 設定が見つからない問題の解決方法

2日前に新しい会社に入社しました。その会社ではIntelli Ideaを使っています。Eclipse...

winx64 での mysql5.7.19 の基本的なインストール プロセス (詳細)

1. ダウンロード参考: https://www.jb51.net/softs/451120.ht...

MySQL の遅いクエリを見つける方法

序文誰もが日常業務で SQL の最適化を経験したことがあると思います。したがって、最適化の前に、遅い...

Vueでブラウザタイトルを動的に設定する方法の詳細な説明

目次ナンセンス文章最初ルーター/index.js 2番目1. プラグインをインストールする2.mai...

CSS3 とテーブルタグを使用して円軌道アニメーションを実装するためのサンプルコード

html: 実際には、テーブルタグに従っていくつかの実線の円 div を正六角形に配置し、div コ...

editplus の Zen コーディング例コードの説明

たとえば、次のように入力します。 XML/HTML コードdiv#ページ>(div#ヘッダー&...

Linux QT Kit が見つからない、バージョンが空の問題の解決策

現在このような問題が発生しています 私の状況は、QT が動かなくなってしまったため、仮想マシンを再起...

MySQL で URL タイムゾーンの罠を回避する方法

序文最近、MySQL 6.0.x 以降の jar を使用する場合、コード URL リンクで serv...

CSS3 FlexBox の伸縮自在なレイアウトを 10 分で理解する

基本的な紹介特徴Flexbox は、よりシンプルで効率的なレイアウト方法を提供する CSS 表示タイ...

MySQL 8.0 WITH クエリの詳細

目次MySQL 8 の WITH クエリについて学ぶ1. 例3. 練習するMySQL 8 の WIT...