사진과 음악을 좋아하는 개발자 지망생의 블로그

[SQL] Redshift 중심의 SQL(기초문법1) 본문

개발/SQL

[SQL] Redshift 중심의 SQL(기초문법1)

devculture309 2023. 5. 9. 17:49
반응형

SQL in Redshift

  - Redshift에서의 SQL은 다르 SQL과 다르지 않다

  - 특히, Posgresql과는 거의 대동소이할 만큼 유사하다

 

1. SQL 기본

  - 다수의 SQL문을 실행한다면 세미콜론으로 분리 필요 (SQL문1;SQL문2;SQL문3;)

  - 주석처리

    ① --: 한주짜리 주석(C, Java에서 //와 같다)

    ② /* -- */: 여러 줄에 걸쳐 사용 가능한 주석

  - SQL 키워드는 대문자를 사용한다던지 하는 나름대로의 포맷팅이 필요하며 특히, 팀 프로젝트라면 팀에서 사용하는

    공통 포맷이 필요하다

  - 테이블/필드이름의 명명규칭을 정하는 것이 중요하다

    ① 단수형 vs 복수형: User vs Users

    ② _ vs CamelCaing: user_session_channel vs UserSessionChannel

  ※ 공통 포맷이나 명명 규칙과 같은 것은 처음부터 잘 잡아두는 것이 좋다

 

2. SQL DDL - 테이블 구조 정의 언어

1) CREATE TABLE

  - Primary Key 속성을 지정할 수 있으나 Uniqueness는 보장하지 않는다(→ 속도 때문)

  - CTAS: CREATE TABEL table_name AS SELECT

  • 테이블을 생성하면서 다른 테이블의 데이터를 선택하여 복사하는 명령어
  • 새로운 테이블을 만들면서 기존의 테이블 데이터를 복사하여 저장할 수 있다

※ CTAS vs CTTI(Create Table Then Insert)

  - CTTI와 CTAS는 기존 테이블에서 데이터를 선택하여 새로운 테이블을 만드는 것으로 비슷한 개념이지만,

    약간의 차이가 있다

   ① CTAS

      - 기존 테이블에서 데이터를 선택하여 새로운 테이블을 만드는 데 사용

      - 보다 빠르고 효율적인 방식이지만, 새로운 테이블이 원본 테이블과 동일한 구조를 가져야한다

      - 기존 데이터를 모두 선택해야 한다는 제약이 있다

  ② CTTI

      - 기존 테이블에서 데이터를 선택하여 새로운 테이블을 만드는 것

      - 새로운 테이블은 기존 테이블의 열 구조와 데이터 유형 등을 상속받는다

      - 이터를 삽입할 필요 없이, SELECT 구문에서 지정한 데이터를 자동으로 새로운 테이블에 저장함

 

2) DROP TABLE

DROP TABLE table_name;

  - 없는 테이블을 지우려고 하는 경우 에러가 발생하므로 다음과 같이 우회한다

DROP TABLE IF EXISTS table_name;

  - vs DELETE FROM

    → DELETE FROM은 조건에 맞는 레코드들을 지우는 것이며, 테이블 자체를 지우는 것은 아니다

 

3) ALTER TABLE

  - 이미 생성된 테이블의 구조를 변경하는 데 사용되는 명령어

  - 새로운 컬럼 추가

ALTER TABLE table_name ADD COLUMN field_name field_type;

  - 기존 컬럼 이름변경:

 ALTER TABLE table_name RENAME current_field_name to new_field_name;

  - 기존 컬럼 제거:

ALTER TABLE table_name DROP COLUMN field_name;

  - 테이블 이름변경:

ALTER TABLE current_table_name RENAME to new_table_name;

 

 

3. SQL DML - 테이블 구조 정의 언어

1) SELECT

  - SELECT FROM: 테이블에서 레코드와 필드를 읽어오는데 사용

  - WHERE를 사용해서 레코드 선택 조건을 지정

  - GROUP BY를 통해 정보를 그룹 레벨에서 뽑는데 사용하기도 함

    → DAU, WAU, MAU 계산은 GROUP BY를 필요로 함

  - ORDER BY를 사용해서 레코드 순서를 결정하기도 함

  - 보통 다수의 테이블의 조인해서 사용하기도 함

SELECT DISTINCT channel			-- 유일한 채널 이름을 알고 싶은 경우
FROM raw_data.user_session_channel;

SELECT channel, COUNT(1)		-- 채널별 카운트를 하고 싶은 경우. COUNT 함수 사용
FROM raw_data.user_session_channel
GROUP BY 1;

SELECT COUNT(1)				-- 테이블의 모든 레코드 수 카운트
FROM raw_data.user_session_channel;

SELECT COUNT(1)				-- channel 이름이 Facebook경우만 고려해서 레코드 수 카운트
FROM raw_data.user_session_channel
WHERE channel = 'Facebook';

 

2) CASE WHEN

  - CASE WHEN 조건 THEN 참일때 값 ELSE 거짓일 때 값 END 필드이름

    → 필드 값의 변환을 위해 사용 가능

  - 여러 조건을 사용하여 변환하는 것도 가능

SELECT
  channel,
  CASE
    WHEN channel in ('Facebook', 'Instagram') THEN 'Social-Media'
    WHEN channel in ('Google', 'Naver') THEN 'Search-Engine'
    ELSE 'Something-Else'
END channel_type
FROM raw_data.user_session_channel
LIMIT 100;

※NULL??

  - 값이 존재하지 않음을 나타내는 상수. NULL != 0, NULL != ""

  - 필드 지정시 값이 없는 경우 NULL로 지정 가능

    → 테이블 정의시 default 값으로도 지정 가능

  - 어떤 필드의 값이 NULL인지 아닌지 비교는 특수한 문법을 필요로 함

    → field1 is NULL or field1 is not NULL

  - NULL이 사칙연산에 사용되면 결과는 → 전 "NULL"

3) COUNT

  - COUNT함수는 인자가 NULL이면 0, NULL이 아니면 1씩 더함

4) WHERE

  - 데이터를 선택하고 검색하는 데 사용되는 조건절

  - SELECT, UPDATE, DELETE 문에서 모두 사용됨

  ① IN

    - WHERE 절에서 여러 값 중 하나에 해당하는 데이터를 검색하는 데 사용

  ② LIKE and  ILIKE

  • LIKE
SELECT *
FROM products
WHERE product_name LIKE 'Apple%';

    - WHERE 절에서 특정 패턴을 가진 문자열을 검색하는 데 사용

    - 패턴은 "%N", "N%", "%N%"로 정의할 수 있

  • ILIKE
SELECT *
FROM products
WHERE product_name ILIKE 'apple%';

    - ILIKE 연산자는 LIKE 연산자와 유사하지만, 대소문자를 구분하지 않음 대소문자에 관계없이 패턴을 검색

③ BETWEEN

SELECT *
FROM products
WHERE price BETWEEN 10 AND 20;

  - WHERE 절에서 지정된 범위 내의 값을 검색하는 데 사용

  - BETWEEN 연산자는 시작 값과 끝 값 사이의 값을 모두 선택

※ 위의 오퍼레이터들은 CASE WHEN 사이에서도 사용 가능

 

5) ORDER BY

  - SELECT 문에서 결과 데이터를 정렬하는 데 사용

  - 내림차순 : DESC / 오름차순 : ASC

  - 컬럼을 겹쳐서 사용할 수 있다

SELECT *
FROM products
ORDER BY product_name ASC, price DESC;

 

6) 타입 변환

  - DATE Conversion

  ① 타임존 관련 변환

    - CONVERT_TIMEZONE('America/Los_Angeles', ts)

    - select pg_timezone_names() → PostgreSQL 데이터베이스에서 사용 가능한 모든 타임존(timezone) 목록을 반환

  ② DATE, TRUNCATE

    - TRUNCATE는 일부 데이터 유형에서만 작동

    - 날짜와 시간 값을 반올림하거나 버리는 데 사용되는 함수

    - 날짜 및 시간 값을 가진 열의 데이터 유형이 DATETIMESTAMP가 아닌 경우, TRUNCATE가 작동하지 않습니다.

SELECT TRUNCATE(sale_date, 'MONTH') FROM sales;
-- 위의 쿼리는 sales 테이블에서 sale_date 열의 월(month) 부분만 남겨두고 나머지를 버리는 작업을 수행

  ③ DATE_TRUNC

    - 특정 기간 단위(년, 월, 일, 시간 등)에서 날짜를 잘라내는 함수

    - 예를 들어, DATE_TRUNC('month', date_column)은 날짜 열(date_column)에서 월(month) 값만 추출

  ④ EXTRACT or DATE_PART

    - 날짜, 시간에서 특정 부분의 값을 추출

  ⑤ DATEDIFF: 두 날짜 값 간의 차이를 계산하는 함수

  ⑥ DATEADD: 특정 날짜 값에 일정한 기간을 더하거나 빼는 함수

  - TO_CHAR: char타입으로 형변환

  - TO_TIMESTAMP: timestamp타입('YYYY-MM-DD HH24:MI:SS')으로 형변환

 

7) 레코드 수정 언어

  - INSERT INTO: 테이블에 레코드를 추가하는데 사용

  - UPDATE FROM: 테이블 레코드의 필드 값 수정

  - DELETE FROM: 테이블에서 레코드를 삭제

 

※ DELETE vs TRUNCATE

  - DELETE 와 TRUNCATE 모두 테이블에서 데이터를 삭제하는 명령어로 비슷한 개념이지만, 동작 방식과 결과

    에서 약간의 차이가 있다

    ① DELETE 

      - 선택한 데이터만 삭제하는 명령어

      - DELETE 문은 WHERE 절을 사용하여 삭제할 행을 지정할 수 있다

      - 테이블의 데이터는 삭제되지만, 테이블의 구조나 고유 식별자는 유지된다

    ② TRUNCATE

      - 테이블에서 모든 데이터를 한 번에 삭제하는 명령어이며, 이 때, 테이블의 구조는 그대로 유지된

      - 테이블의 데이터를 모두 삭제하고 테이블의 고유 식별자(예: 시퀀스 번호)도 초기화된다

      - 초기화 작업은 테이블의 자동 증가 열을 다시 1부터 시작하도록 설정하는 데 유용

      - TRUNCATE는 DELETE보다 더 빠르지만, 복구할 수 없다

 

반응형