サーチ…


前書き

SELECTは、1つまたは複数のテーブルから選択された行を取り出すために使用されます。

構文

  • SELECT DISTINCT [expressions] FROM TableName [WHERE条件]; ///シンプルセレクト

  • SELECT DISTINCT(a)、b ...はSELECT DISTINCT a、bと同じです。

  • SELECT [すべて| DISTINCT | DISTINCTROW] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT | SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]表のFROM表[WHERE条件] [GROUP BY式] [HAVING条件] [ORDER BY式[ASC | DESC]] [LIMIT [オフセット値] number_rows | LIMIT number_rows OFFSET offset_value] [プロシージャプロシージャ名] [INTO [OUTFILE 'file_name' options | DUMPFILE 'file_name' | @ variable1、@ variable2、... @variable_n] [FOR UPDATE |共有モードでロック]; ///完全選択構文

備考

MySQLのSELECT文の詳細については、 MySQL Docsを参照してください。

列名による選択

CREATE TABLE stack(
    id INT,
    username VARCHAR(30) NOT NULL,
    password VARCHAR(30) NOT NULL
);

INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');

クエリ

SELECT id FROM stack;

結果

+------+
| id   |
+------+
|    1 |
|    2 |
+------+

すべての列を選択(*)

クエリ

SELECT * FROM stack;

結果

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
|    2 | stack    | stack    |
+------+----------+----------+
2 rows in set (0.00 sec)

次のようにして、結合の1つの表からすべての列を選択できます。

SELECT stack.* FROM stack JOIN Overflow ON stack.id = Overflow.id;

ベストプラクティスは使用しないでください*あなたが連想配列に行(複数可)をデバッグしたりフェッチされていない限り、そうでない場合は、スキーマの変更は、(列を並べ替える/ / DROPをADD)厄介なアプリケーションエラーが発生する可能性があり、。また、結果セットに必要なカラムのリストを与えると、MySQLのクエリプランナーはしばしばクエリを最適化できます。

長所:

  1. 列を追加/削除するときに、 SELECT *使用した場所を変更する必要はありません。
  2. それは書くのが短くて
  3. 答えも表示されるので、 SELECT * -usageは正当化されますか?

短所:

  1. あなたは必要以上のデータを返しています。行ごとに200kを含むVARBINARY列を追加するとします。このデータは、1レコードにつき1つの場所にしか必要ではありませんSELECT *を使用すると、必要でない10行につき2MBを返すことになります
  2. 使用されるデータについての明示
  3. 列を指定すると、列が削除されたときにエラーが発生する
  4. クエリプロセッサはもう少し作業をしなければなりません。テーブル上にどのような列が存在するのかを把握する必要があります(@vinodadhikaryに感謝します)
  5. 列がより簡単に使用される場所を見つけることができます
  6. SELECT *を使用すると、すべての列が結合されます。
  7. 序数参照は安全に使用することはできません(ただし、序数参照を使用するのは悪い習慣です)
  8. TEXTフィールドを使用する複雑なクエリでは、最適でない一時テーブル処理によってクエリが遅くなることがあります

WHEREを使用したSELECT

クエリ

SELECT * FROM stack WHERE username = "admin" AND password = "admin";

結果

+------+----------+----------+
| id   | username | password |
+------+----------+----------+
|    1 | admin    | admin    |
+------+----------+----------+
1 row in set (0.00 sec) 

WHERE句でネストされたSELECTを使用したクエリ

WHERE句には、より複雑なクエリを書くための任意の有効なSELECT文を含めることができます。これは 'ネストされた'クエリです

クエリ

ネストされたクエリは、通常、クエリの単一のアトミック値を比較のために返すために使用されます。

SELECT title FROM books WHERE author_id = (SELECT id FROM authors WHERE last_name = 'Bar' AND first_name = 'Foo');

電子メールアドレスのないすべてのユーザー名を選択します。

SELECT * FROM stack WHERE username IN (SELECT username FROM signups WHERE email IS NULL);

免責事項:結果セット全体を比較するとき 、パフォーマンスの向上にジョインを使用することを検討してください。

LIKE(%)を伴うSELECT

CREATE TABLE stack
(  id int AUTO_INCREMENT PRIMARY KEY,
   username VARCHAR(100) NOT NULL
);

INSERT stack(username) VALUES 
('admin'),('k admin'),('adm'),('a adm b'),('b XadmY c'), ('adm now'), ('not here'); 

どこでも "adm"

SELECT * FROM stack WHERE username LIKE "%adm%";  
+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  2 | k admin   |
|  3 | adm       |
|  4 | a adm b   |
|  5 | b XadmY c |
|  6 | adm now   |
+----+-----------+

"adm"で始まります:

SELECT * FROM stack WHERE username LIKE "adm%";
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
|  3 | adm      |
|  6 | adm now  |
+----+----------+

"adm"で終わります:

SELECT * FROM stack WHERE username LIKE "%adm"; 
+----+----------+
| id | username |
+----+----------+
|  3 | adm      |
+----+----------+

LIKE句の%文字が任意の数の文字と一致するのと同様に、 _文字はただ1つの文字と一致します。例えば、

SELECT * FROM stack WHERE username LIKE "adm_n"; 
+----+----------+
| id | username |
+----+----------+
|  1 | admin    |
+----+----------+

パフォーマンスノート usernameにインデックスがある場合、

  • LIKE 'adm'は `= 'adm'と同じことを実行します
  • LIKE 'adm%BETWEEN..AND..同様の「範囲」 BETWEEN..AND..列のインデックスをうまく利用することができます。
  • LIKE '%adm' (または主要ワイルドカードを有する任意の変異体)は、任意のインデックスを使用することができません。したがって、それは遅くなります。行数が多い表では、速度が遅い可能性があり、無駄です。
  • RLIKEREGEXP )はLIKEよりも遅くなる傾向がありますが、より多くの機能があります。
  • MySQLが提供しているがFULLTEXTテーブルと列の多くの種類のインデックスを、それらのFULLTEXTインデックスを使用してクエリ履行するために使用されていない LIKE

別名付きセレクト(AS)

SQLエイリアスは、テーブルまたは列の名前を一時的に変更するために使用されます。これらは一般的に可読性を向上させるために使用されます。

クエリ

SELECT username AS val FROM stack; 
SELECT username val FROM stack;

(注: ASは構文的にオプションです。)

結果

+-------+
| val   |
+-------+
| admin |
| stack |
+-------+
2 rows in set (0.00 sec)

LIMIT句を含むSELECT

クエリ:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 3;

結果:

顧客ID 顧客名連絡先住所シティ郵便番号
1

アルフレッド・フッタキステマリアアンダース Obere Str。 57 ベルリン 12209 ドイツ
2 アナトラジーロEmparedados y helados アナトラヒョ Avda。デラコンスティチオン2222 メキシコDF 05021 メキシコ
3 アントニオ・モレノ・テケリアアントニオ・モレノマタデロス2312 メキシコDF 05023 メキシコ

ベストプラクティス LIMIT使用する場合は常にORDER BYを使用してください。そうしないと、取得する行は予測できなくなります。

クエリ:

 SELECT *
   FROM Customers
  ORDER BY CustomerID 
  LIMIT 2,1;

説明:

LIMIT句に2つの数値が含まれている場合、 LIMIT LIMIT offset,countとして解釈されLIMIT offset,count 。したがって、この例では、2つのレコードをスキップして1つを返します。

結果:

顧客ID 顧客名連絡先住所シティ郵便番号
3 アントニオ・モレノ・テケリアアントニオ・モレノマタデロス2312 メキシコDF 05023 メキシコ

注意:

LIMIT句の値は定数でなければなりません。列の値ではない可能性があります。

DISTINCTを指定したSELECT

SELECT後のDISTINCT句は、結果セットから重複行をDISTINCT

CREATE TABLE `car`
(   `car_id` INT UNSIGNED NOT NULL PRIMARY KEY, 
    `name` VARCHAR(20), 
    `price` DECIMAL(8,2)
);

INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');

SELECT DISTINCT `name`, `price` FROM CAR;
+---------+----------+
| name    | price    |
+---------+----------+
| Audi A1 | 20000.00 |
| Audi A1 | 15000.00 |
| Audi A2 | 40000.00 |
+---------+----------+

DISTINCT 、個々の列ではなく、結果を出力するために、すべての列にわたって機能します。後者は、しばしば新しいSQL開発者の誤解です。要するに、結果セットの行レベルでの区別は、列レベルでの区別ではなく重要である。これを視覚化するには、上記の結果セットの "Audi A1"を見てください。

MySQLのそれ以降のバージョンでは、 DISTINCTORDER BYと一緒に使用することに意味を持ちます。 ONLY_FULL_GROUP_BYの設定は、以下のMySQLマニュアルページの「 GROUP BYのMySQL処理 」に示されているように機能します。

LIKE(_)を含むSELECT

LIKE句パターンの_文字は、1文字に一致します。

クエリ

SELECT username FROM users WHERE users LIKE 'admin_';

結果

+----------+
| username |  
+----------+
| admin1   |
| admin2   |
| admin-   |
| adminA   |
+----------+

CASEまたはIFでのSELECT

クエリ

SELECT st.name,
       st.percentage, 
       CASE WHEN st.percentage >= 35 THEN 'Pass' ELSE 'Fail' END AS `Remark` 
FROM student AS st ;

結果

+--------------------------------+
|   name   | percentage | Remark |
+--------------------------------+
|   Isha   |     67     |  Pass  |
|   Rucha  |     28     |  Fail  |
|   Het    |     35     |  Pass  |
|   Ansh   |     92     |  Pass  |
+--------------------------------+

またはIF

SELECT st.name,
       st.percentage, 
       IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark` 
FROM student AS st ;

NB

IF(st.percentage >= 35, 'Pass', 'Fail')

これは次のことを意味します:IF st.percentage> = 35がTRUEならば'Pass'返しますELSEは'Fail'

選択肢間のSELECT

BETWEEN句を使用して、「より大きいANDより小さい等しい」条件の組み合わせを置き換えることができます。

データ

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
|  6 | java      |
+----+-----------+

オペレータによるクエリ

SELECT * FROM stack WHERE id >= 2 and id <= 5; 

BETWEENと同様のクエリ

SELECT * FROM stack WHERE id BETWEEN 2 and 5; 

結果

+----+-----------+
| id | username  |
+----+-----------+
|  2 | root      |
|  3 | toor      |
|  4 | mysql     |
|  5 | thanks    |
+----+-----------+
4 rows in set (0.00 sec)

注意

BETWEENは>=<= 、not ><ます。

NOT BETWEENを使用する

ネガを使用する場合はNOTを使用できます。例えば ​​:

SELECT * FROM stack WHERE id NOT BETWEEN 2 and 5; 

結果

+----+-----------+
| id | username  |
+----+-----------+
|  1 | admin     |
|  6 | java      |
+----+-----------+
2 rows in set (0.00 sec)

注意

使用の間にない><なく>=<=すなわち、 WHERE id NOT BETWEEN 2 and 5と同じであるWHERE (id < 2 OR id > 5)

BETWEEN検索で使用するカラムにインデックスがある場合、MySQLはそのインデックスをレンジスキャンに使用できます。

日付範囲を含むSELECT

SELECT ... WHERE dt >= '2017-02-01'
             AND dt  < '2017-02-01' + INTERVAL 1 MONTH

確かに、これはBETWEEN23:59:59組み込みで行うことができます。しかし、このパターンには次の利点があります。

  • 終了日を事前に計算する必要はありません(開始日から正確な長さになることが多い)
  • 両方のエンドポイント( BETWEENように)を含めず、また '23:59:59'と入力しないでください。
  • これは、 DATETIMESTAMPDATETIME 、さらにはマイクロ秒に含まれるDATETIME(6)ます。
  • 閏年、年末などの処理を行います。
  • それはインデックスに優しい( BETWEEN )。


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow