본문 바로가기
WIKI 기술 지식 베이스

표현식

원문 보기 위키 갱신

표현식 (Expressions)

리터럴, 연산자, CAST, CASE, 서브쿼리를 포함한 SQL 표현식 문법을 정리한 문서예요. 하나씩 짚어보면 SQL 작성 감각이 확 붙을 거예요.

출처: 문서

본문

표현식은 Turso가 평가해서 결과를 만들어 내는 값, 연산자, 함수의 조합이에요. 표현식은 SELECT 컬럼, WHERE 조건, ORDER BY, GROUP BY, HAVING, CHECK 제약, DEFAULT 값 등 많은 SQL 절에 나타나요.

Literals

Numeric Literals

SELECT 42;           -- integer literal
SELECT -17;          -- negative integer
SELECT 3.14;         -- real (floating-point) literal
SELECT 2.5e10;       -- scientific notation
SELECT 0xFF;         -- hexadecimal integer (255)

String Literals

문자열 리터럴은 작은따옴표로 감싸요. 문자열 안에 작은따옴표를 넣으려면 작은따옴표를 연속 두 개 쓰면 돼요:

SELECT 'hello world';        -- text literal
SELECT 'it''s a test';       -- embedded single quote
SELECT '';                   -- empty string

Blob Literals

Blob 리터럴은 x 또는 X가 앞에 붙은 16진수 문자열이에요:

SELECT x'CAFEBABE';          -- blob literal
SELECT X'48454C4C4F';        -- blob literal (case insensitive prefix)

NULL Literal

SELECT NULL;                 -- null value

Boolean Literals

Turso에는 별도의 boolean 타입이 없어요. 정수 0(거짓)과 1(참)을 사용하세요:

SELECT 1;    -- true
SELECT 0;    -- false

Operators

Arithmetic Operators

Operator Description Example Result
+ 덧셈 3 + 4 7
- 뺄셈 10 - 3 7
* 곱셈 3 * 4 12
/ 나눗셈 10 / 3 3 (정수 나눗셈)
- (unary) 부정 -5 -5
+ (unary) no-op +5 5

정수 나눗셈은 0 방향으로 절삭해요. 부동소수점 나눗셈을 하려면 CAST를 쓰거나 1.0을 곱하세요:

SELECT 10 / 3;           -- 3 (integer division)
SELECT 10 / 3.0;         -- 3.333... (real division)
SELECT CAST(10 AS REAL) / 3;  -- 3.333...

Comparison Operators

Operator Description Example
= 또는 == 같음 x = 5
!= 또는 <> 같지 않음 x != 5
< 미만 x < 5
> 초과 x > 5
<= 이하 x <= 5
>= 이상 x >= 5

모든 비교 연산자는 1(참), 0(거짓), NULL(피연산자 중 하나가 NULL이면)을 반환해요.

Logical Operators

Operator Description Example
AND 논리 AND x > 0 AND x < 10
OR 논리 OR x = 1 OR x = 2
NOT 논리 NOT NOT x = 5

Bitwise Operators

Operator Description Example Result
& 비트 AND 5 & 3 1
| 비트 OR 5 | 3 7
~ 비트 NOT ~5 -6
<< 왼쪽 시프트 1 << 4 16
>> 오른쪽 시프트 16 >> 2 4

String Concatenation

Operator Description Example Result
|| 연결 'hello' || ' ' || 'world' 'hello world'

피연산자 중 하나가 배열이면 ||는 대신 배열 연결을 수행해요. Array Operators를 보세요.

Array Operators

Turso Extension: 배열 연산자는 SQLite에는 없는 Turso 전용 기능이에요.

Operator Description Example Result
@> 모두 포함 ARRAY[1,2,3] @> ARRAY[1,2] 1
&& 겹침 ARRAY[1,2,3] && ARRAY[3,4,5] 1
|| 배열 연결 ARRAY[1,2] || ARRAY[3,4] [1,2,3,4]
=, !=, <, >, <=, >= 비교 ARRAY[1,2] < ARRAY[1,3] 1

@> 연산자는 왼쪽 배열이 오른쪽 배열의 모든 요소를 포함하는지 검사해요. && 연산자는 두 배열이 공통 요소를 하나라도 공유하는지 검사하고요. 둘 다 1(참) 또는 0(거짓)을 반환해요.

배열 비교는 왼쪽부터 요소 단위로 이루어져요. 비교한 요소가 모두 같으면 더 짧은 배열이 더 작은 것으로 간주돼요.

SELECT ARRAY[1,2,3] @> ARRAY[1,3];     -- 1 (contains both 1 and 3)
SELECT ARRAY[1,2] && ARRAY[3,4];       -- 0 (no common elements)
SELECT ARRAY[1,2] < ARRAY[1,2,3];      -- 1 (shorter is less)

전체 레퍼런스는 Array Functions를 보세요.

CAST Expression

CAST 표현식은 값을 지정한 타입으로 변환해요.

CAST(expression AS type-name)
Parameter Type Description
expression any 변환할 값
type-name type 대상 타입 이름
SELECT CAST(3.7 AS INTEGER);    -- 3 (truncates toward zero)
SELECT CAST(42 AS TEXT);         -- '42'
SELECT CAST('123' AS INTEGER);   -- 123
SELECT CAST('abc' AS INTEGER);   -- 0
SELECT CAST(NULL AS INTEGER);    -- NULL

Turso Extension: 커스텀 타입이 있는 STRICT 테이블에서는 CAST(value AS custom_type)가 커스텀 타입의 ENCODE 함수를 적용해요. 자세한 내용은 CREATE TYPE을 보세요.

COLLATE Expression

COLLATE 표현식은 문자열 비교를 위한 collation sequence를 지정해요.

expression COLLATE collation-name

내장 collation sequence는 다음과 같아요:

Collation Description
BINARY 바이트 단위 비교 (기본값)
NOCASE ASCII 문자에 대해 대소문자 구분 없는 비교
RTRIM BINARY와 같지만 끝의 공백은 무시해요
SELECT 'ABC' = 'abc';                        -- 0 (BINARY comparison)
SELECT 'ABC' = 'abc' COLLATE NOCASE;          -- 1 (case-insensitive)
SELECT 'abc ' = 'abc' COLLATE RTRIM;           -- 1 (trailing space ignored)

SELECT name FROM users ORDER BY name COLLATE NOCASE;

Pattern Matching

LIKE Operator

LIKE 연산자는 대소문자 구분 없는 패턴 매칭을 수행해요(ASCII 문자 기준). % 와일드카드는 임의의 문자 시퀀스와 일치하고, _는 임의의 한 문자와 일치해요.

expression [NOT] LIKE pattern [ESCAPE escape-char]
SELECT 'Hello World' LIKE 'hello%';         -- 1 (case-insensitive)
SELECT 'Hello World' LIKE 'H_llo%';         -- 1 (_ matches 'e')
SELECT 'Hello World' LIKE '%World';          -- 1
SELECT '10%' LIKE '10\%' ESCAPE '\';        -- 1 (escaped % literal)

GLOB Operator

GLOB 연산자는 Unix 스타일 와일드카드로 대소문자 구분 있는 패턴 매칭을 수행해요. *는 임의의 문자 시퀀스와 일치하고, ?는 임의의 한 문자와 일치해요.

expression [NOT] GLOB pattern
SELECT 'Hello' GLOB 'H*';      -- 1
SELECT 'Hello' GLOB 'h*';      -- 0 (case-sensitive)
SELECT 'Hello' GLOB 'H?llo';   -- 1
SELECT 'Hello' GLOB 'H[a-z]*'; -- 1 (character class)

REGEXP Operator

REGEXP 연산자는 정규 표현식 매칭을 수행해요. regexp 확장이 필요해요(기본으로 로드돼요).

expression [NOT] REGEXP pattern
SELECT 'Hello123' REGEXP '[A-Za-z]+[0-9]+';  -- 1
SELECT '[email protected]' REGEXP '^[^@]+@[^@]+\.[^@]+$';  -- 1

BETWEEN Expression

BETWEEN 표현식은 값이 포함 범위 안에 있는지 검사해요.

expression [NOT] BETWEEN low AND high

BETWEEN 표현식은 expression >= low AND expression <= high와 동일해요:

SELECT 5 BETWEEN 1 AND 10;     -- 1
SELECT 5 NOT BETWEEN 1 AND 3;  -- 1
SELECT 'b' BETWEEN 'a' AND 'c'; -- 1

IN Expression

IN 표현식은 값이 목록이나 서브쿼리 결과의 어떤 값과 일치하는지 검사해요.

expression [NOT] IN (value1, value2, ...)
expression [NOT] IN (select-statement)
SELECT 3 IN (1, 2, 3, 4, 5);           -- 1
SELECT 'red' NOT IN ('blue', 'green');   -- 1

SELECT name FROM users
WHERE id IN (SELECT user_id FROM orders WHERE total > 100);

EXISTS Expression

EXISTS 표현식은 서브쿼리가 최소 한 행을 반환하면 1, 아니면 0을 반환해요.

[NOT] EXISTS (select-statement)
SELECT EXISTS (SELECT 1 FROM users WHERE name = 'Alice');  -- 1 if Alice exists

SELECT name FROM departments d
WHERE EXISTS (
    SELECT 1 FROM employees e
    WHERE e.department_id = d.id
);

IS NULL / IS NOT NULL

IS NULL 표현식은 값이 NULL인지 검사해요. 항상 NULL을 반환하는 = NULL과 달리, IS NULL은 1 또는 0을 반환해요.

expression IS NULL
expression IS NOT NULL
SELECT NULL IS NULL;       -- 1
SELECT NULL = NULL;        -- NULL (not 1!)
SELECT 42 IS NOT NULL;     -- 1
SELECT NULL IS NOT NULL;   -- 0

IS DISTINCT FROM

IS DISTINCT FROM 표현식은 NULL을 비교 가능한 값으로 다루면서 두 값을 비교해요.

expression IS [NOT] DISTINCT FROM expression
SELECT 1 IS DISTINCT FROM 2;       -- 1 (different values)
SELECT 1 IS DISTINCT FROM 1;       -- 0 (same value)
SELECT NULL IS DISTINCT FROM NULL;  -- 0 (both NULL)
SELECT NULL IS DISTINCT FROM 1;     -- 1 (NULL vs non-NULL)
SELECT 1 IS NOT DISTINCT FROM 1;    -- 1

CASE Expression

CASE 표현식은 SQL 표현식 안에서 조건 로직을 제공해요.

Simple CASE

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    [ELSE default_result]
END

Searched CASE

CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    [ELSE default_result]
END

WHEN 절이 하나도 일치하지 않고 ELSE 절도 없으면 CASE 표현식은 NULL을 반환해요.

-- Simple CASE
SELECT name,
    CASE status
        WHEN 'A' THEN 'Active'
        WHEN 'I' THEN 'Inactive'
        ELSE 'Unknown'
    END AS status_text
FROM users;

-- Searched CASE
SELECT name, score,
    CASE
        WHEN score >= 90 THEN 'A'
        WHEN score >= 80 THEN 'B'
        WHEN score >= 70 THEN 'C'
        ELSE 'F'
    END AS grade
FROM students;

Scalar Subqueries

괄호로 감싸서 단일 값을 반환하는 서브쿼리는 표현식으로 쓸 수 있어요.

(select-statement)

서브쿼리는 정확히 한 컬럼과 최대 한 행을 반환해야 해요. 서브쿼리가 행을 반환하지 않으면 표현식은 NULL로 평가돼요.

SELECT name,
    (SELECT COUNT(*) FROM orders WHERE orders.user_id = users.id) AS order_count
FROM users;

SELECT * FROM products
WHERE price > (SELECT AVG(price) FROM products);

RAISE Function

RAISE 함수는 오류 조건을 발생시켜요. 표준 SQLite에서 RAISE는 트리거 안에서만 쓸 수 있지만, Turso에서는 RAISE(ABORT, msg)를 트리거 밖에서도 쓸 수 있어요 — CHECK 제약, 커스텀 타입 ENCODE 표현식, 독립 실행 쿼리에서요. 다른 형태(RAISE(IGNORE), RAISE(ROLLBACK, msg), RAISE(FAIL, msg))는 트리거 안에서만 유효해요.

RAISE(IGNORE)
RAISE(ROLLBACK, error-message)
RAISE(ABORT, error-message)
RAISE(FAIL, error-message)
Form Description
RAISE(IGNORE) 현재 트리거 동작을 중단하되 문장은 계속 진행해요
RAISE(ROLLBACK, msg) 문장을 중단하고 현재 트랜잭션을 롤백해요
RAISE(ABORT, msg) 현재 문장을 중단해요; 트랜잭션의 이전 변경은 유지돼요
RAISE(FAIL, msg) 현재 시점에서 현재 문장을 중단해요; 이전 행 변경은 유지돼요
-- In a trigger
CREATE TRIGGER validate_age BEFORE INSERT ON users
BEGIN
    SELECT CASE
        WHEN NEW.age < 0 THEN RAISE(ABORT, 'age must be non-negative')
    END;
END;

-- In a custom type ENCODE expression
CREATE TYPE positive_int BASE integer
    ENCODE CASE WHEN value > 0 THEN value
                ELSE RAISE(ABORT, 'value must be positive') END
    DECODE value;

Operator Precedence

연산자는 다음 순서로 평가돼요(우선순위가 높은 것부터):

Precedence Operators
1 (highest) ~ (unary NOT), + (unary), - (unary)
2 || (concatenation)
3 *, /
4 +, -
5 <<, >>, &, |
6 <, <=, >, >=, @>, &&
7 =, ==, !=, <>, IS, IS NOT, IS DISTINCT FROM, IN, LIKE, GLOB, REGEXP, BETWEEN
8 NOT
9 AND
10 (lowest) OR

필요하면 괄호로 우선순위를 바꿀 수 있어요:

SELECT 2 + 3 * 4;       -- 14 (multiplication first)
SELECT (2 + 3) * 4;     -- 20 (parentheses override)

See Also

  • Data Types — 스토리지 클래스와 타입 어피니티
  • Scalar Functions — 표현식에서 쓸 수 있는 내장 함수
  • SELECT — 쿼리에서 표현식 사용하기

더 알아보기 (Learn more)