> For the complete documentation index, see [llms.txt](https://www.ducksql.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.ducksql.com/sql/select.md).

# SELECT 기본

## Table 이란?

테이블은 DB에서 데이터를 저장해두는 공간입니다. 엑셀의 sheet와 비슷하며, 차이점은 미리 컬럼의 이름과 데이터 형식을 정해둔다는 것 입니다. 대표적인 데이터 형식은 int(숫자), text(텍스트), timestamp(날짜)가 있습니다.

| id (int) | name (text)  | birth (timestamp) |
| -------- | ------------ | ----------------- |
| 1        | Heehong Moon | 1986-08-20        |
| 2        | Sunny Kim    | 1989-10-04        |
| 3        | Morning Moon | 2022-09-05        |

일반적으로 각 테이블에는 숫자로 된 id를 가지도록 테이블을 디자인 합니다. id는 고유값으로 특정한 row를 지칭할때 사용됩니다.

## SELECT의 기본 모양

```sql
-- users 이라는 테이블에 있는 id, name, birth 컬럼의 데이터를 가져옵니다.
SELECT id, name, birth 
FROM users;
```

테이블에 정의된 모든 컬럼을 가져오기 위해서 아래와 같이 간단하게 \* 을 사용할 수 있습니다.

```sql
-- users 테이블의 전체를 리턴합니다.
SELECT * 
FROM users;
```

## 조건식

전체 테이블에서 어떠한 조건을 만족하는 데이터만 가져오기 위해서는  WHERE 절을 이용합니다.&#x20;

```sql
-- users 테이블에서 id가 1인 행만 리턴합니다.
SELECT *
FROM users
WHERE id = 1;
```

숫자나 텍스트 형식에 사용할수 있는 다양한 조건 오퍼레이터가 있습니다. 대표적으로 사용되는 오퍼레이터 예제입니다.

| 오퍼레이터        | 의미                     | 예제                         |
| ------------ | ---------------------- | -------------------------- |
| =, !=        | 같다 또는 다르다.             | col\_name != 3             |
| >, >=, <, <= | 크다, 크거나 같다, 작다, 작거나 같다 | col\_name >= 10            |
| IN (...)     | 하나라도 같은게 있다            | col\_name IN (3, 6, 9)     |
| NOT IN (...) | ... 중 같은게 하나도 없다.      | col\_name NOT IN (3, 6, 9) |

여러가지 조건을 동시에 만족하는 행만 리턴하기 위해서는 AND 또는 OR 를 사용합니다. AND는 두 조건 모두 만족하는 경우, OR는 두 조건 중 하나만 만족해도 결과에 포함됩니다.

```sql
-- 2022년 1월 1일 이후 출생이면서 이름이 Heehong Moon인 유저를 가져옵니다.
SELECT *
FROM users
WHERE name = 'Heehong Moon' AND birth > '2022-01-01'
```

{% hint style="info" %}
텍스트를 조건으로 사용할때는 항상 Single Quote(')를 사용하여 묶어야 합니다. Double Quote(")를 사용하면 정상동작 하지 않습니다.
{% endhint %}

## NULL

데이터가 없는 없을 의미할때 NULL을 사용합니다. 주의 해야 할점은 데이터가 없는 조건을 걸때는 등호(=, !=)로 쿼리하면 안되고 IS, IS NOT 오퍼레이터를 사용해야 합니다.

| 오퍼레이터       | 의미      | 예제                    |
| ----------- | ------- | --------------------- |
| IS NULL     | 데이터가 없음 | col\_name IS NULL     |
| IS NOT NULL | 데이터가 있음 | col\_name IS NOT NULL |

## 정렬

조건식에 맞는 행을 어떤 순서로 정렬할지 정할수 있습니다. 특정 컬럼의 오름차순 또는 내림 차순으로 정렬할 수 있습니다.

기본값은 오름차순이며, 오름차순일때는 ASC, 내림 차순은 DESC 로 지정합니다.

```sql
-- id 가 1보다 큰 유저의 생일을 내림차순으로 가져옵니다.
SELECT *
FROM users
WHERE id >= 1
ORDER BY birth DESC
```

정렬 순서를 여러개 지정하려면 콤마로 할수 있습니다.

```sql
-- 생일 내림차순으로 정렬, 생일이 같은 경우 id를 오름차순으로 정렬
SELECT *
FROM users
ORDER BY birth DESC, id ASC
```

## LIMIT

쿼리에서 가져오는 데이터 개수를 제한합니다. 쿼리의 조건식에 부합하는 행이 100개 라도 LIMIT 10을 하면 10개만 가져옵니다.

```sql
-- 1990년 이후 출생한 유저의 3명만 가져옵니다.
SELECT *
FROM users 
WHERE birth > '1990-01-01'
ORDER BY birth DESC
LIMIT 3
```

## 연습

### 데이터

{% file src="/files/L0Box9lkvDEt8XIQsYON" %}

* id : 고유 id
* kakao\_id : 카카오로 가입한 유저의 id
* fb\_id : 페이스북으로 가입한 유저의 id
* google\_id : 구글로 가입한 유저의 id
* name : 유저 이름
* created\_time : 가입일
* last\_login : 마지막 로그인 시간

### 문제

* id가 207751 보다 큰 유저
* 이름이 Lois Wagner 인 유저
* 구글로 가입한 유저 10명
* 카카오로 가입한 유저 3명을 가입일 내림차순으로 정렬
* 페이스북으로 가입한 유저 중 2020-12월 이후 로그인 한 유저
