MySQL
セレクト
サーチ…
前書き
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のクエリプランナーはしばしばクエリを最適化できます。
長所:
- 列を追加/削除するときに、
SELECT *
使用した場所を変更する必要はありません。 - それは書くのが短くて
- 答えも表示されるので、
SELECT *
-usageは正当化されますか?
短所:
- あなたは必要以上のデータを返しています。行ごとに200kを含むVARBINARY列を追加するとします。このデータは、1レコードにつき1つの場所にしか必要ではありません
SELECT *
を使用すると、必要でない10行につき2MBを返すことになります - 使用されるデータについての明示
- 列を指定すると、列が削除されたときにエラーが発生する
- クエリプロセッサはもう少し作業をしなければなりません。テーブル上にどのような列が存在するのかを把握する必要があります(@vinodadhikaryに感謝します)
- 列がより簡単に使用される場所を見つけることができます
- SELECT *を使用すると、すべての列が結合されます。
- 序数参照は安全に使用することはできません(ただし、序数参照を使用するのは悪い習慣です)
-
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'
(または主要ワイルドカードを有する任意の変異体)は、任意のインデックスを使用することができません。したがって、それは遅くなります。行数が多い表では、速度が遅い可能性があり、無駄です。 -
RLIKE
(REGEXP
)は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のそれ以降のバージョンでは、 DISTINCT
はORDER 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
確かに、これはBETWEEN
と23:59:59
組み込みで行うことができます。しかし、このパターンには次の利点があります。
- 終了日を事前に計算する必要はありません(開始日から正確な長さになることが多い)
- 両方のエンドポイント(
BETWEEN
ように)を含めず、また '23:59:59'と入力しないでください。 - これは、
DATE
、TIMESTAMP
、DATETIME
、さらにはマイクロ秒に含まれるDATETIME(6)
ます。 - 閏年、年末などの処理を行います。
- それはインデックスに優しい(
BETWEEN
)。