수색…


소개

SELECT 는 하나 이상의 테이블에서 선택된 행을 검색하는 데 사용됩니다.

통사론

  • 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 [offset_value] number_rows | LIMIT number_rows OFFSET offset_value] [프로 시저 프로 시저 _ 이름] [INTO [OUTFILE 'file_name'옵션 | DUMPFILE 'file_name'| @ variable1, @ variable2, ... @variable_n] [FOR UPDATE | LOCK IN SHARE MODE]; /// 전체 선택 구문

비고

MySQL의 SELECT 문에 대한 자세한 내용은 MySQL 문서를 참조하십시오.

열 이름 별 선택

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)

다음을 수행하여 조인에서 한 테이블의 모든 열을 선택할 수 있습니다.

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

모범 사례 행을 디버깅하거나 연관 배열로 페치하지 않는 한 * 사용하지 마십시오. 그렇지 않으면 스키마 변경 (ADD / DROP / 열 재 배열)으로 인해 응용 프로그램 오류가 발생할 수 있습니다. 또한 결과 집합에 필요한 열의 목록을 제공하면 MySQL의 쿼리 계획자는 종종 쿼리를 최적화 할 수 있습니다.

장점 :

  1. 열을 추가 / 제거 할 때 SELECT * 사용한 위치를 변경할 필요가 없습니다.
  2. 쓰기가 더 짧다.
  3. 또한 답을 볼 수 있으므로 SELECT * -usage가 정당화 될 수 있습니까?

단점 :

  1. 필요한 것보다 많은 데이터를 반환하고 있습니다. 행 당 200k를 포함하는 VARBINARY 열을 추가한다고합시다. 하나의 레코드에 대해서만이 데이터가 필요합니다 - 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);

면책 조항 : 전체 결과 집합을 비교할 때 성능 향상을 위해 조인 을 사용하는 것을 고려하십시오.

좋아하는 선택 (%)

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 절의 % 문자가 임의의 수의 문자와 일치하는 것처럼 _ 문자는 한 문자와 일치합니다. 예를 들어,

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

성능 노트 username 인덱스가있는 경우

  • LIKE 'adm' 은`= 'adm'
  • LIKE 'adm%BETWEEN..AND.. 와 유사한'범위 '입니다. 열의 색인을 잘 활용할 수 있습니다.
  • LIKE '%adm' (또는 선도적 인 와일드 카드 어떤 변형) 어떤 인덱스를 사용할 수 없습니다. 그러므로 그것은 느릴 것입니다. 행이 많은 테이블에서는 너무 느려서 쓸모가 없습니다.
  • RLIKE ( REGEXP )는 LIKE 보다 느린 경향이 있지만 더 많은 기능이 있습니다.
  • MySQL이 제공하는 동안 FULLTEXT 테이블과 컬럼의 많은 종류에 색인을, 그 FULLTEXT 인덱스를 사용하여 쿼리를 수행하는 데 사용되지 않습니다 LIKE .

별칭 (AS)이있는 SELECT

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

알프레드 Futterkiste 마리아 앤더스 Obere Str. 57 번 베를린 12209 독일
2 Ana Trujillo Emparedados y helados 아나 트루 질로 Avda. 드 라 콘 스티 치온 2222 멕시코 DF 05021 멕시코
안토니오 모레노 타 케리아 안토니오 모레노 Mataderos 2312 멕시코 DF 05023 멕시코

모범 사례 LIMIT 사용할 때는 항상 ORDER BY 를 사용하십시오. 그렇지 않으면 얻을 수있는 행은 예측할 수 없게됩니다.

질문:

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

설명:

LIMIT 절이 두 개의 숫자를 포함하면 LIMIT offset,count 로 해석됩니다. 따라서이 예에서 쿼리는 두 개의 레코드를 건너 뛰고 하나를 반환합니다.

결과:

고객 ID 고객 이름 담당자 이름 주소 시티 우편 번호 국가
안토니오 모레노 타 케리아 안토니오 모레노 Mataderos 2312 멕시코 DF 05023 멕시코

노트 :

LIMIT 절의 값은 상수 여야합니다. 열 값이 아닐 수도 있습니다.

DISTINCT가있는 SELECT

SELECTDISTINCT 절은 결과 집합에서 중복 행을 제거합니다.

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 username FROM users WHERE users LIKE 'admin_';

결과

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

CASE 또는 IF로 선택

질문

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 ;

주의

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

즉, IF st.percentage> = 35가 TRUE 이면 'Pass' 를 반환 합니다. ELSE는 'Fail' 반환합니다.

선택 사항과 함께 선택

BETWEEN 절을 사용하여 "보다 크고 같음보다 작음"조건의 조합을 바꿀 수 있습니다.

데이터

+----+-----------+
| 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)

노트

사용법 >< 및 not >=<= 즉, WHERE id NOT BETWEEN 2 and 5WHERE (id < 2 OR id > 5) 와 동일 WHERE id NOT BETWEEN 2 and 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'를 입력하지 마십시오.
  • DATE , TIMESTAMP , DATETIME 및 마이크로 초 포함 DATETIME(6) 합니다.
  • 윤년, 연말 등을 처리합니다.
  • 인덱스 친화적입니다 (따라서 BETWEEN ).


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow