SELECT 문으로 테이블에서 행 읽어오기
SQLite 데이터베이스에 던지는 모든 질문은 SELECT로 시작합니다. 의미를 그대로 풀어 보면 _이 테이블에서, 이런 조건에 맞는 행의, 이 컬럼들을 달라_는 뜻이죠. 이번 문서에서는 앞의 두 가지, 즉 어떤 컬럼을 어떤 테이블에서 가져올지에 집중합니다. 조건으로 걸러내는 부분은 다음 문서에서 다룹니다.
가장 단순한 형태의 쿼리는 이렇습니다:
SELECT *는 "모든 컬럼"을 의미하고, FROM products는 조회할 테이블을 지정합니다. 결과로는 레코드마다 한 행씩, 네 개 컬럼이 모두 포함되어 나옵니다. 마지막 세미콜론은 문장의 끝을 나타냅니다.
기본 형태는 이렇게 단순합니다: SELECT <컬럼들> FROM <테이블>;.
sqlite에서 특정 컬럼만 조회하기
*는 데이터를 가볍게 둘러볼 때는 편하지만, 실제 코드에서는 필요한 컬럼만 골라서 명시하는 편이 거의 항상 낫습니다:
요청한 순서대로 두 개의 컬럼이 그대로 돌아옵니다. SELECT 절에 적은 순서가 결과의 컬럼 순서를 결정하기 때문에, 테이블에 정의된 컬럼 순서와 굳이 일치할 필요는 없습니다.
그렇다면 SELECT * 대신 컬럼명을 일일이 적는 게 왜 더 좋을까요? 이유는 두 가지입니다. 첫째, 네트워크로(혹은 파일에서) 오가는 데이터 양이 줄어듭니다. 컬럼이 많은 테이블일수록 체감 효과가 큽니다. 둘째, 다음 달에 누가 테이블에 컬럼을 하나 추가해도 쿼리가 그대로 안전합니다. SELECT *는 어느 순간부터 슬그머니 더 많은 컬럼을 반환하기 시작하고, 위치 기반으로 행을 풀어 쓰는 애플리케이션 코드는 이때 깨지기 쉽습니다.
SELECT는 단순 조회뿐 아니라 계산도 할 수 있다
SELECT 절에 들어가는 항목이 꼭 원본 컬럼명일 필요는 없습니다. 산술 연산, 함수 호출, 문자열 결합, 상수 등 어떤 표현식이든 올 수 있죠. SQLite는 각 행마다 이 표현식을 평가해서 결과를 만들어 냅니다.
네 번째 컬럼은 사실 테이블에 존재하지 않습니다. SQLite가 행마다 직접 계산해서 만들어낸 값이죠. 이런 식으로 문자열 함수, 날짜, 조건식 등 무엇이든 활용할 수 있습니다. SELECT 절은 단순히 데이터를 꺼내오는 곳이 아니라, 원하는 형태로 데이터를 가공하는 공간이라고 보시면 됩니다.
심지어 FROM 절 없이 SELECT만 써서 SQLite를 계산기처럼 쓸 수도 있습니다:
한 행에 세 개의 컬럼이 나옵니다. 실제 쿼리에 넣기 전에 어떤 표현식이 어떻게 동작하는지 미리 확인할 때 유용합니다.
AS로 컬럼에 별칭 붙이기
계산식으로 컬럼을 만들면 SQLite가 알아서 이름을 붙여 주는데, 보통 price * stock처럼 표현식 자체가 컬럼명이 됩니다. 보기에도 별로고, 표현식이 조금만 바뀌어도 이름이 따라 바뀌어서 불안정하죠. 이럴 때는 AS로 제대로 된 이름을 지정해 줍니다:
별칭은 결과셋에서 해당 컬럼의 이름으로 쓰입니다. 출력 결과를 눈으로 확인할 때 가독성이 좋아지고, 무엇보다 컬럼 이름으로 값을 꺼내 쓰는 애플리케이션 코드(row[1] 대신 row["inventory_value"])에서 큰 차이가 납니다.
AS 키워드는 사실 생략해도 됩니다. price * stock inventory_value라고 써도 똑같이 동작하죠. 그래도 AS를 명시하는 습관을 들이세요. 의도가 분명해지고, 쉼표를 빠뜨린 건지 별칭을 붙인 건지 헷갈리는 상황도 막을 수 있습니다.
테이블에도 별칭 붙이기
테이블 자체에도 짧은 별칭을 붙일 수 있습니다. 테이블이 하나뿐일 땐 큰 의미가 없지만, JOIN을 쓰기 시작하는 순간부터 이 습관이 빛을 발합니다.
p는 이제 products를 가리키는 단축 이름입니다. p.name처럼 점(.)을 찍어 표기하면 해당 컬럼이 어느 테이블에서 왔는지 명확하게 드러납니다. 테이블이 하나뿐일 때는 그저 군더더기처럼 보이지만, 세 개의 테이블을 조인하는 상황에선 이 표기법이 쿼리의 가독성을 지켜주는 유일한 장치가 됩니다.
SELECT 결과에 리터럴과 상수 함께 넣기
실제 컬럼과 고정된 값을 함께 조회할 수도 있습니다. 행마다 태그를 붙이거나 자리표시자 값을 채워 넣고 싶을 때 유용한 방식입니다.
모든 행이 똑같이 'USD'와 1 값을 갖게 됩니다. 이 패턴은 UNION으로 여러 쿼리 결과를 합칠 때, 어느 쿼리에서 온 데이터인지 구분할 표시용 컬럼이 필요한 상황에서 자주 등장합니다.
NULL에 대해 짚고 넘어가기
어떤 컬럼은 값이 비어 있습니다. 데이터를 넣을 때 값을 지정하지 않았거나, 컬럼에 기본값이 없는 경우죠. SQLite는 "값이 없음"을 NULL로 표현하며, SELECT 결과에 나타나는 NULL은 사용하는 도구에 따라 빈 칸으로 보이기도 하고 NULL이라는 글자 그대로 출력되기도 합니다.
두 번째 행을 살펴보세요. price가 NULL이면 price * 2도 NULL이 됩니다. NULL이 들어간 산술 연산은 무조건 NULL을 뱉기 때문이죠. SQL 결과가 이상하게 나올 때 가장 흔히 의심해야 할 원인 중 하나인데, 이 주제는 따로 한 페이지를 할애해서 다룰 예정입니다. 지금은 NULL이 표현식을 따라 전염된다는 사실만 기억해 두세요.
핵심 정리
- 모든 쿼리의 기본 형태는
SELECT <컬럼들> FROM <테이블>;입니다. - 실제 코드에서는 컬럼을 하나하나 명시하고,
SELECT *는 데이터를 둘러볼 때만 쓰세요. SELECT절에는 컬럼명뿐 아니라 어떤 표현식이든 올 수 있습니다.- 계산 결과 컬럼이나 테이블에 별칭을 줄 때는
AS를 활용하세요. - 산술 연산에서
NULL은 그대로 전파됩니다 — 결과가 이상해 보이면 이걸 먼저 의심하세요.
다음 글: WHERE로 행 필터링하기
지금까지의 쿼리는 테이블의 모든 행을 그대로 가져왔습니다. 여기서 원하는 행만 골라내려면 WHERE 절이 필요합니다. 가격, 이름, 날짜 등 참/거짓으로 평가되는 어떤 표현식이든 조건으로 걸 수 있죠. 이 내용은 다음 글에서 이어집니다.
자주 묻는 질문
SQLite SELECT 문의 기본 문법이 어떻게 되나요?
기본 형태는 SELECT <컬럼> FROM <테이블>; 입니다. 컬럼 자리에는 SELECT name, email FROM users처럼 쉼표로 구분한 컬럼 목록을 쓰거나, 모든 컬럼을 가져오는 *, 또는 price * quantity 같은 표현식도 올 수 있어요. FROM 절에 읽어올 테이블 이름을 적고, 마지막은 세미콜론(;)으로 마무리합니다.
SQLite에서 SELECT *를 써도 괜찮을까요?
CLI에서 테이블 내용을 슥 훑어볼 때는 편하게 써도 됩니다. 다만 실제 애플리케이션 코드에서는 필요한 컬럼만 명시하는 게 안전해요. SELECT *는 현재 스키마에 코드가 강하게 묶여 버려서, 내일 컬럼 하나만 추가돼도 쿼리가 조용히 더 많은 데이터를 반환합니다. 결과를 인덱스 순서로 꺼내 쓰는 코드라면 그대로 깨질 수 있죠.
SELECT 결과의 컬럼 이름을 바꾸려면 어떻게 하나요?
AS 키워드로 별칭(alias)을 붙이면 됩니다. 예를 들어 SELECT price * quantity AS total FROM orders처럼 쓰면, 결과 셋에서 컬럼 이름이 total로 나옵니다. 가독성도 좋아지고, 컬럼명을 키로 결과를 꺼내는 코드에서도 중요해요. AS는 생략해도 되지만, 의도를 분명히 드러내려면 그대로 쓰는 걸 추천합니다.