問題の声明
データベースを指定すると、次の形式の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リファレンスガイドがあります