サンプルの問題を含むSQLの基本

このガイドでは、小さなタスクの例として基本的なsqlコマンドを見ていきます。 読むときは、mysqlコンソールに座って、より明確にするためにすべてのクエリを入力することをお勧めします。



問題の声明



データベースを指定すると、次の形式の3つのテーブルがあります。









table1:user_id(INT(5)、PRIMARY KEY)、ユーザー名(VARCHAR(50)、INDEX)

table2:phone_id(INT(5)、PRIMARY KEY)、user_id(INT(5)、INDEX)、phone_number(INT(10)、INDEX)

table3:room_id(INT(5)、PRIMARY KEY)、phone_id(INT(5)、INDEX)、room_number(INT(4)INDEX)



ユーザーがニックネームquxで座っている部屋の番号を選択する必要があります...



タスク用のデータの準備



CREATE DATABASEおよびCREATE TABLEステートメントは、それぞれデータベースとテーブルの作成(DROP DATABASEとDROP TABLEの削除)に使用されます。 各コマンドの最後にはセミコロン(;)があります。 最初に、articleというデータベースを作成します。



CREATE DATABASE IF NOT EXISTS article;
      
      





キーワードIF NOT EXISTSを使用して、指定されたデータベースまたはテーブルが既に存在する場合にエラーが発生しないようにします(将来、IF NOT EXISTSは簡略化のために省略されます)。

次に、テーブルを作成する必要があります。



 CREATE TABLE `table1` (`user_id` INT(5) NOT NULL AUTO_INCREMENT, `username` VARCHAR(50), PRIMARY KEY(`user_id`), INDEX(`username`)); CREATE TABLE `table2` (`phone_id` INT(5) NOT NULL AUTO_INCREMENT, `user_id` INT(5) NOT NULL, phone_number INT(10) NOT NULL, PRIMARY KEY (`phone_id`), INDEX(`user_id`, `phone_number`)); CREATE TABLE `table3` (`room_id` INT(5) NOT NULL AUTO_INCREMENT, `phone_id` INT(5) NOT NULL, `room_number` INT(4) NOT NULL, PRIMARY KEY(`room_id`), INDEX(`phone_id`, `room_number`));
      
      





これらのコマンドを順番に分析します。 CREATE TABLEの後に、テーブルの名前が示され、括弧内に、コンマとキー指示で区切られたタイプと属性を持つフィールドの名前が示されます。 最初のコマンドは、table1という名前とuser_id、usernameフィールドを持つテーブルを作成します。 user_idフィールドは整数型(INT)で、5文字の長さであり、ゼロにすることはできず、auto_increment属性(各レコードを作成すると、このフィールドの値は自動的に作成され、1ずつ増加します)に加えて、それが主キーです。 [主キーは一意のインデックスの一例であり、テーブルエントリを一意に識別するために使用されます。 2つのテーブルエントリに同じプライマリキー値を設定することはできません。 ]ユーザー名フィールドは文字タイプ(255文字長)であり、インデックスです。 2番目と3番目のチームは最初のチームに似ています。



データベースにあるテーブルを確認するには、次のコマンドを使用できます。



 SHOW TABLES;
      
      





次に、テーブルにデータを追加する必要があります。 レコードを追加するには、INSERTステートメントを使用します。



 INSERT INTO table1 (username) VALUE ('foo');
      
      





user_idフィールドには何も追加しません。これは、INSERTごとに自動的に作成されるためです(魔法の属性auto_incrementを思い出します)。 テーブルの名前を角かっこで囲んだ後(これらの角かっこをタプルと呼びます)、値を割り当てるフィールドのリストを示します。 VALUEの後、値自体が示されます。 タプル内の適切な位置になければなりません。

同じコマンドでbar、baz、quxユーザーを追加します。

確認するには、次のコマンドを使用します。



[1]
 SELECT * FROM table1;
      
      





SELECTコマンド自体については、後で詳しく説明します。

次に、テーブルtable2とtable3を埋めます。



[2]
 INSERT INTO table2 (user_id, phone_number) VALUE ('2','200');
      
      





ここで、user_idフィールドには値2が割り当てられ、phone_numberフィールドには200が設定されます。タプル内のフィールド名または値を交換すると、結果が変わります。 例:



[3]
 INSERT INTO table2 (user_id, phone_number) VALUE ('200','2');
      
      





これで、user_idは200に、phone_numberは2に設定されます。

値を追加するときに間違えた場合([2]ではなく[3]コマンドを使用)、テーブルまたはデータベース全体を削除するために中断する必要はありません。値はUPDATEステートメントを使用して変更できます。



 UPDATE table2 SET user_id='2', phone_number='200' WHERE phone_id='1';
      
      





SETの後、値を変更する必要があるフィールドを示し、それに応じて等号を介して新しい値を示します。 WHERE演算子が初めて表示されます。 要求に制限を課す必要があります。 この場合、変更はテーブルのすべての行に適用されるのではなく、phone_idフィールドの値が「1」である行にのみ適用されます。

残りのデータは類推によって追加されます(ページの上部で追加する内容を確認できます)。



解決策



データベースとテーブルを作成しました。 これで、問題自体に取り組むことができます。 データベース内の選択は、SELECTステートメントを使用して実行されます。SELECTステートメントは、コマンドにある程度精通しています[1]。 もっと詳しく考えてみましょう。 一般的には、次のようになります。

SELECT field_name FROM table_name WHERE句[ORDER BY、LIMIT]

ORDER BYおよびLIMITは追加オプションです。

それを適用してみましょう。 テーブルtable1からユーザー名フィールドのすべての値を選択します。



 SELECT username FROM table1;
      
      





そしてそれらを並べ替える



 SELECT username FROM table1 ORDER BY username;
      
      





ご覧のとおり、ORDER BYは、SELECTステートメントの後に指定されたフィールドの1つでソートするために使用されます。 デフォルトでは、逆順でソートを使用したい場合、増分ソートが行われ、フィールドの後にDESCを追加する必要があります。



 SELECT username FROM table1 ORDER BY username DESC;
      
      





すべての値が必要なので、WHERE演算子は省略できます。 別の例:table2のphone_idおよびuser_idフィールドの値を選択します。phone_numberは「200」です。



 SELECT phone_id, user_id FROM table2 WHERE phone_number=200; SELECT phone_id, user_id FROM table2 WHERE phone_number=200 LIMIT 1, 3;
      
      





LIMITは、指定された範囲の行を表示します(下限は含まれません)。 最初の引数が指定されていない場合、0と等しいと見なされます。



ご覧のとおり、3つのテーブルはすべて関連しています。 フィールドuser_idを介したtable1とtable2、およびphone_idを介したtable2とtable3。 それらを指定された列にリンクするには、JOIN演算子を使用する必要があります。 JOINは、偉大で強力に翻訳され、「団結する」、つまり複数のピースから1つの全体を組み立てることを意味します。 MySQLデータベースでは、これらの「スライス」は、フェッチ時に組み合わせることができるテーブルフィールドです。 結合を使用すると、1つのクエリで複数のテーブルからデータを取得できます。 結果の要件に応じて、MySQLは次の3種類の結合を許可します。

1.内部結合(クロス結合)-内部(クロス)結合

2. LEFT JOIN-左側の外部結合

3. RIGHT JOIN-右翼外部協会



INNER JOINを使用すると、結合されたすべてのテーブルに必ず存在する行を取得できます。

クエリを書きましょう:



[4]
 SELECT table3.room_number FROM table1 INNER JOIN table2 USING(user_id) INNER JOIN table3 USING(phone_id) WHERE table1.username = 'qux';
      
      





USING演算子を使用して、テーブルをリンクするフィールドを指定します。 フィールドの名前が同じ場合にのみ使用できます。 それ以外の場合は、以下に示すようにONを使用する必要があります。



 SELECT table3.room_number FROM table1 INNER JOIN table2 ON table1.user_id = table2.user_id INNER JOIN table3 ON table2.phone_id = table3.phone_id WHERE table1.username = 'qux';
      
      





LEFT / RIGHT JOINを使用すると、テーブルからデータを取得し、可能であれば別のテーブルのデータを補完できます。 INNER JOINとの違いを示すために、最初にtable1に別のフィールドを追加する必要があります。



 INSERT INTO table1 (username) VALUE ('quuz');
      
      





そして、コマンド[4]を使用し、INNER JOINをLEFT JOINに、quxをquuzに置き換えます。



 SELECT table3.room_number FROM table1 LEFT JOIN table2 USING(user_id) LEFT JOIN table3 USING(phone_id) WHERE table1.username = 'quuz';
      
      





次の結果が得られます。





新しいユーザーはuser_id = 5を受け取りました。 この値は他のテーブルにはないため、結果としてNULLになりました。 INNER JOINでは、すべてのテーブルにある値のみが出力されるため、結果は空になります。 ここでは、table1とtable2が存在しなくても、table3の値で補完されます。



付録



以下に、少し説明したコマンドの例を示します。



テーブルtable1からuser_idが1の行を削除します。

 DELETE FROM table1 WHERE user_id = 1;
      
      





テーブルtable1の名前をnyaに変更します。

 RENAME TABLE table1 TO nya;
      
      





user_idフィールドの名前をid(テーブルtable1)に変更します。

 ALTER TABLE table1 CHANGE user_id id INT;
      
      





phone_numberフィールドのタイプと属性を変更します。

 ALTER TABLE table2 MODIFY phone_number VARCHAR(100) NOT NULL;
      
      





テーブルtable1の説明を表示します。

 DESCRIBE table1;
      
      





DATE型のabraフィールドを追加します。

 ALTER TABLE table3 ADD abra DATE;
      
      





room_numberが数字3で始まるroom_idフィールドのすべての値をtable3から選択します(%は任意の文字数を意味します。文字列が指定されたパターンに一致するかどうかのチェックのように)。

 SELECT room_id FROM table3 WHERE room_number LIKE '3%';
      
      







PS



1.参加に関する資料の一部は、 JOINに関するMySQLの記事から少し引用されています

2.タスクは、私が行ったインタビューの1つで満たされました。 非常に合成的ですが、素材の説明に適しています。

3.演算子の構造の説明は、初心者が理解しやすいように意図的に簡略化されています。 他の皆のために、 MySQLリファレンスガイドがあります



All Articles