환율을 결정짓는 원인

1. 양국간의 금리차

2. 무역 수지 & 자본 수지

3. 타국과의 경제 밸런스

국가 기준 금리 10월 말 장기 금리 장기 금리
미국 5.5% 5.0% 3.9%
한국 3.5% 4.4% 3.3%
일본 -0.1% 1.0% 0.6%

※ 기준 금리 : 중앙 은행과 시중 은행과의 거래에 사용되는 금리

※ QT : 양적 긴축

※ QE : 양적 완화

※ 초과지준금리 : 시중은행이 예치한 지급준비금 초과분에 연준이 제공하는 이자

 

옛날에는 단기 금리를 봤는데, 최근에는 장기 금리의 영향도 높아졌다.

10월 말에 비해 미국과 일본의 금리 차이가 줄어 들었다.

 

일본 엔화 강세는 나타날 것인가.

연준에서 긴축 사이클에 들어가면서 금리를 계속 올리려고 하면 한국은 덜 딸려 올라가고 일본은 거의 올라가지 못한다. 즉 엔화가 원화 대비보다도 약해진다고 볼 수 있다.

만약 내년부터 금리 인하가 시작된다고 본다면, 미국과 한국의 금리는 빨리 내려올수록 엔화는 상대적으로 강세를 보일 수 있다.

"금리 인하" 한다는 이야기가 나온다면, 현재 10년물 금리는 미국은 6~7차례 기준 금리 인하를 반영한 금리라고 볼 수 있는데, 그렇다면 엔화가 강세가 되려면 3.9%보다 더 많이 인하된다는 기대감이 반영되어야 엔화의 가격이 오르게 될 것이다. 그런데 만약에 연준이 그정도로 인하를 하지 않는다고 한다면 엔화의 강세는 나타나지 못하게 된다. 즉, 엔화는 강세가 되었다가 약세가 되었다가하는 반복되는 장세를 보일 가능성이 높다. 결국 엔화는 중장기적으로 볼 때 엔화의 강세가 나올 순 있으나, 그 길이 순탄치는 않을 것 같다.

 

그렇다면 일본의 정책 변화가 나타난다면 엔화가 강세를 보여줄 수도 있겠으나  現 BOJ 총제 우에다의 11월 발언를 보면, "일본 물가가 옛날에 비해 올라오고 있기 때문에, 연말부터 내년초까지는 이런 현상이 완화적인 정책을 쓰고 있는 일본 은행 입장에서는 큰 도전적인 시기가 될 것 같다." 발언 이후, 12월 Boj 회의에서 정책 변경이 일어나는 것 아니냐고 시장에서 기대했지만, 정작 12월 회의에서는 현 정책을 고수하겠다고 발표하면서 큰 실망감을 얻었다.

 

FOMC, 피벗은 언제부터?

12월 FOMC에서 중요한 내용을 요약하자면 아래와 같다.

 

첫 번째, 시중 금리에 관하여

11월에 financial Condition의 시중금리가 너무 높게 올라오다보니 연준에서 추가적인 기준 금리 인상은 안해도 되는 것 아닌가라는 이야기가 있었고, 이에 반응한 시장은 12월 달부터 시작해서 국채 금리가 빠르게 내려와 5.0%에서 4.15%까지 내려오게 되었다. 그래서 12월 FOMC에서는 금리 환경이 완화되었으니, 금리 인상은 아니더라도 지켜본다는 발표가 있을 것이라 예측했는데, 파월 의장은 금융 시장하고 중앙 은행하고 하는 기대가 다를 수 있다고 밝혔다. 즉, 금융 시장에서 금리가 내려갈 땐 신경쓰지 않겠다는 뜻이었고 이는 금리가 올라가는 것이 두려운 것인지 내려가는 것은 별 신경 쓰지 않겠다는 스텐스의 발언이었다.

 

두 번째, 금리 인하에 대한 시그널

긴축 사이클이 시작한 2022년 초부터 항상 나타나는 패턴이 있었는데, 연준은 점도표에서 금리를 높게 찍었다. 이를 보고 시장이 아니라고 했다가 따라가고, 했다가 따라가는 양상이 반복되었고, 최종적으로 연준에서 점도표를 5.5%~5.75%까지 찍었다. 이에 시장은 5.25%~5.5%를 찍게 되었다. 이후, 12월 FOMC에서 financial Condition에 대해서 이야기하면서 시장에서는 연준에서 5.5%~5.75%까지는 못 올릴 것이다라고 확신을 가지게 되었다.

연준은 2024년 점도표에서 3번 인하하고 2025년에 추가 4번 인하한다고 이야기하고 있다. 즉 2년간 7번 인하할 것이다라고 말하고 있다. 하지만 시장에서는 내년에 6,7번을 할 것으로 예측하고 있다. 즉 시장에서는 연준이 기대하는 것보다는 더 빠르고 더 많이 인하하는 것을 기대하고 있다.

 

세 번째, QT(양적 긴축)에 대한 이야기

역레포의 금액이 2조 달러에서 빠르게 줄어들고 있는데, 이것이 양적 긴축에 영향을 줄 수 있는 것 아닌가라는 질문에 파월 의장은 큰 영향을 주지 않을 것 같고 양적 긴축은 스케쥴대로 밀고 갈 것이다라고 발언하였다. 

 

시장이 이렇게 반응하는 이유가 무엇인가.

과거 미국 실업률 데이터를 보자면  실업률이 최저치까지 낮아졌다가 경제 침체와 함께 실업률이 최고치까지 올라가는 경향을 보였다. 과거를 보았을 때 연준은 성장에 대해서 신경을 쓸 수 밖에 없을 것이다.

18년~20년 금리 데이터를 보자면 금리를 계속 올리면서 18년 10월부터 점차 회사채, 신흥국 시장이 무너지기 시작했다. 이후 연준에서 금리 인상을 멈추고 시장에게 오히려 끌려가기 시작했다.

이런 경험을 통해서 연준은 한 번 끌려오기 시작하면 끌려올 수 밖에 없다는 생각을 가지게 된 것이다.

'경제 > 주식' 카테고리의 다른 글

용어 정리  (0) 2024.01.20

1.3 부동산 대책은 한마디로 정의 하자면 청약 규제를 문제인 정권 이전으로 돌려 놨다고 볼 수 있다.

규제 지역을 대폭적으로 축소했다. 이에 따라 각종 세금이나 대출 규제가 포함되어 있는데, 이런 사안들이 풀리다보니 비규제 거래 활성화, 대출 활성화 등이 나오게 되고 스멀스멀 부동산 가격이 올라가기 시작했다.

하반기에는 전고점 가격까지 돌아오다보니 더이상 올라갈 동력을 잃게 되었다. 예를 들어 목동 7단지 24억5천까지 찍었는데 전고점이 25억이었다. 데드캣 바운드라는 용어처럼 너무 많이 뛰어 오른것아닌가? 라는 생각을 가지게 되었다.

강남 3구, 동부 이촌동 등 누구든 들어가고 싶어하는 지역은 이미 2022년 전으로 모두 회복되었다고 보인다.

 

비규제 지역이기 때문에, 투자심리가 몰렸던 곳은 규제 지역으로 묶여있던 상급지가 풀리면 가장 먼저 투자가 위축되게 된다. 왜냐하면 대다수가 원하는 상급지가 비규제 지역이 되었기 때문이다.

 

지방의 회복율이 더딘 이유는 비관론이 팽배해져있기 때문이다. 그 중 하나는 인구 감소이다. 통계만 보더라도 인구의 감소에 따른 수요의 감소라는 대전제를 무시하지 못하는 것이다. 통계청에서 발표한 자료를 보면 광역시를 제외하고 대다수 도시의 인구수가 하락세이다.

'경제 > 부동산' 카테고리의 다른 글

최근 부동산 시장 예측 ft.이광수 대표  (0) 2024.02.07
권리분석 - 유치권  (0) 2024.02.04
경매 관련 사이트  (0) 2024.02.01
2024년 1.10 부동산 정책 정리  (1) 2024.01.13

▣ 문자열 함수

  • 데이터를 여러 형태로 바꾸다 보면 문자열을 조작해야 하는 경우가 많으므로 빅쿼리는 내장 문자열 함수 라이브러리를 제공한다.
WITH
  example AS(
  SELECT
    *
  FROM
    UNNEST ( ['Seatle','New York', 'Singapore'] ) AS city )
SELECT
  city,
  LENGTH(city) AS len,
  LOWER(city) AS lower,
  STRPOS(city, 'or') AS orpos
FROM
  example

  • 이 쿼리는 문자열의 길이를 계산해 문자열을 소문자로 만든 후 'city' 컬럼에서 부분 문자열의 위치를 찾는다.
  • 부분 문자열 'or'은 'new york' 및 'Singapore'에서 찾을 수 있지만 'Seattle'에서는 찾을 수 없다.
  • 문자열 조작에 특히 유용한 두 가지 기능은 SUBSTR 및 CONCAT 이다. SUBSTR은 부분 문자열을 추출하고 CONCAT는 입력값을 연결한다. 
WITH example AS (
    SELECT 'armin@abc.com' AS email, 'Annapolis, MD' AS city
    UNION ALL SELECT 'boyan@bca.com', 'Boulder, CD'
    UNION ALL SELECT 'carrie@cab.com', 'Chicago, IL'
)
SELECT 
    CONCAT(
        SUBSTR(email, 1, STRPOS(email,'@') -1), --username
        ' from ', city) AS callers
FROM example


■ 국제화

  • 빅쿼리의 문자열은 유니코드이므로 영어와 관계된 가정은 피해야 한다. 예를 들어 일본어에는 '대문자'라는 것이 없으며, 문자열 타입을 바이트 배열 타입으로 변환할 때 기본적으로 적용되는 UTF-8 인코딩은 타밀어 같은 언어를 제대로 표현하지 못한다.
WITH
  example AS(
  SELECT
    *
  FROM
    UNNEST( [ 'Seattle', 'New York', '東京' ] ) AS city )
SELECT
  city,
  UPPER(city) AS allcaps,
  CAST(city AS BYTES ) AS bytes
FROM
  example

 

내 컴퓨터에 타밀어는 없으므로 패스.

  • 빅쿼리는 유니코드 문자 배열, 바이트 배열 및 유니코드 코드 포인트 배열(int 64)로 문자열을 나타내는 3가지 방법을 지원한다.
  • 동일한 문자열에서 CHAR_LENGTH 및 BYTE_LENGTH 결과와 코드 포인트 수가 문자 수와 어떻게 다른지 확인하자.
WITH
  example AS(
  SELECT *
  FROM
    UNNEST( [ 'Seattle','New York', '東京' ] ) AS city )
SELECT
  city,
  CHAR_LENGTH(city) AS char_len,
  to_code_points(city)[ORDINAL(1)] AS first_codept , 
  ARRAY_LENGTH(to_code_points(city)) AS num_codept,
  CAST (city AS bytes) AS bytes,
  BYTE_LENGTH(city) AS byte_len
FROM
  example

 

  • 따라서 어떤 열에 다른 언어로 된 텍스트가 포함되어 있는지 파악한 후 언어의 차이를 고려해서 문자열 조작 함수를 사용해야 한다.

■ 출력 및 파싱

  • 문자열을 파싱할 때는 간단히 INT64나 FLOAT64 타입으로 변환하면 되지만, 어떤 값을 원하는 형태의 문자열로 표현하라면 FORMAT 함수를 사용해야 한다.
SELECT
  CAST(42 AS STRING),
  CAST ('42' AS INT64),
  FORMAT ('%03d',42),
  FORMAT('%6.3f', 32.457842),
  FORMAT('%5.3f', 32.4),
  FORMAT('**%s**','H'),
  FORMAT('%s-%03d','Agent',7)

  • FORMAT은 C의 printf 함수와 유사하게 작동하며 같은 형식 지정자를 사용한다. 좀 더 유용한 지정자 중 몇몇은 앞의 예에서 설명했다.
  • FORMAT 함수는 날짜나 타임스탬프 값도 지원하지만, 사용자의 로케일을 감안해서 날짜를 형식화할 수 있는 FORMAT_DATE와 FORMAT_TIMESTAMP 함수를 사용하는 것이 더 좋다.

■ 문자열 조작 함수

  • 문자열 조작은 ETL 파이프라인에서 일반적으로 필요하므로, 다음 편의 함수를 잘 기억해 두면 유용한다.
SELECT
  ENDS_WITH('hello', 'o') --TRUE
 , ENDS_WITH('hello','h') --FALSE
 , STARTS_WITH('hello','h') --FALSE
 , STRPOS('hello','e') --2
 , STRPOS('hello','f') --0 FOR NOT-found
 , SUBSTR('hello',2,4) --1-based
 , CONCAT('hello','World')

  • SUBSTR( )의 작동 방식을 주목.
  • 첫 번째 파라미터는 시작 위치이며, 두 번째 파라미터는 하위 문자열에서 원하는 문자 수다.

■ 변환 함수

SELECT 
LPAD('Hello', 10, '*') AS LPAD --왼쪽에 *가 추가된다.
, RPAD('Hello', 10, '*') AS RPAD--오른쪽에 *가 추가된다.
, LPAD('Hello',10) AS LPAD  -- 왼쪽에 공백이 추가된다.
, LTRIM('Hello') AS LTRIM-- 왼쪽의 공백이 제거된다.
, RTRIM('Hello') AS RTRIM-- 오른쪽의 공백이 제거된다.
, TRIM('Hello') AS TRIM-- 양쪽의 공백이 제거된다.
, TRIM('***Hello***', '*') AS TRIM_2-- 양쪽의 *이 제거된다.
, REVERSE('Hello') AS REVERSE-- 문자열이 뒤바뀐다.


■ 정규 표현식

  • 정규 표현식은 편의 함수들보다 강력하다. 예를 들어 STRPOS 함수 등은 특정 문자만 찾을 수 있지만, REGEXP_CONTAINS를 사용하면 강력한 검색을 수행할 수 있다.
  • 예를 들어 컬럼에 미국 우편번호가 포함되어 있는지를 판별하려면 다음 쿼리를 사용하면 된다.(짧은 형식은 5자리 숫자이며, 긴 형식은 추가 4자리 숫자를 하이픈 또는 공백으로 구분한다.)
SELECT
  COLUMN,
  REGEXP_CONTAINS(COLUMN,r'\d{5}(?:[-\s]\d{4})?') has_zipcode,
  REGEXP_CONTAINS(COLUMN,r'^\d{5}(?:[-\s]\d{4})?$') is_zipcode,
  REGEXP_EXTRACT(COLUMN,r'\d{5}(?:[-\s]\d{4})?') the_zipcode,
  REGEXP_EXTRACT_ALL(COLUMN,r'\d{5}(?:[-\s]\d{4})?') all_zipcode,
  REGEXP_REPLACE(COLUMN,r'\d{5}(?:[-\s]\d{4})?', '*****') masked
FROM (
  SELECT
    *
  FROM
    UNNEST([ '12345', '1234','12345-9876', 'abc 12345 def', 'abcde-fghi', '12345 ab 34567', '12345 9876' ]) AS COLUMN )

  • 정규 표현식 \d{5}는 5개의 10진수로 구성된 문자열과 일치한다.
  • 괄호로 묶인 표현식의 두 번째 부분은 하이픈 또는 공백(\s)으로 분리되는 첫 번째 5개 10진수와 분리된 4개의 10진수(\d{4})의 선택적(괄호 끝에 ? 표시함) 그룹(?:)을 찾는다.
  • 문자열에 \d, \s 등이 있으면 문제가 발생할 수 있으므로 문자열 앞에 r(원시)을 붙여 문자열 리터럴로 만들었다.
  • 두 번째 표현식은 정확히 일치하는 경우를 보여준다. 지정된 문자열로 시작(^)하고 끝나야 ($) 한다고 보면 된다.
  • 정규식과 일치하는 문자열 부분을 추출하려면 REGEXP_EXTRACT를 사용한다. 식이 일치하지 않으면 NULL을 반환하고, 일치하는 항목이 여러 개 있으면 첫 번째로 일치하는 값만 반환한다.
  • REGEXP_EXTRACT_ALL은 모두 일치하는 항목을 반환한다. 일치하는 것이 없으면 빈 배열을 반환한다.
  • REGEXP_REPLACE는 모든 일치 항목을 대체 문자열로 바꾼다.
  • 빅쿼리의 정규 표현식은 구글의 오픈 소스인 RE2 라이브러리의 규칙을 따른다.

■ 문자열 함수 정리

  • 데이터 분석에서 문자열 데이터는 매우 흔하므로 사용 가능한 함수를 폭넓게 학습하는 것이 좋다. 정확한 문법에 대해서는 빅쿼리 공식문서를 참조한다.
유형 함수 설명
문자열 표현 CHAR_LENGTH, BYTE_LENGTH, TO_CODE_POINTS, CODE_POINTS_TO_STRING, SAFE_CONVERT_BYTES_TO_STRING, TO_HEX, TO_BASE32, TO_BASE64, FROM_HEX, FROM_BASE32, FROM_BASE64, NORMALIZE 다른 유니코드 공백 문자를 같은 것으로 취급하게 하는 등의 정규화를 실행한다.
출력 및 파싱 FORMAT, REPEAT, SPLIT FROMAT 구문은 C의 printf와 비슷하다. format("%03d", 12)는 012를 반환한다.로케일 기준 변환에는 FORMAT_DATE 등을 사용한다.
편의성 ENDS_WITH, LENGTH, STARTS_WITH, STRPOS, SUBSTR, CONCAT LENGTH 함수는 문자열이면 CHAR_LENGTH, 바이트면 BYTE_LENGTH와 같다.
문자열 변형 LPAD, LOWER, LTRIM, REPLACE, REVERSE, RPAD, RTRIM, TRIM, UPPER 기본 문자열 자르기(trim) 구분자는 유니 코드 공백이지만 다른 trim 문자를 지정할 수 있다.
정규 표현식 REGEXP_CONTAINS, REGEXP_EXPTRACT. REGEXP_EXTRACT_ALL, REGEXP_REPLACE 빅쿼리에서 허용하는 구문은 깃허브 구글문서를 참조한다.

 

▣ Bool 다루기

  • 불리언 변수는 True 또는 False 중 하나의 값만 갖는 변수다. SQL은 대소문자를 구분하지 않으므로 TRUE나 true나 모두 같은 의미를 갖는다.

■ 논리 연산

  • 필터링에 대해 설명할 때 WHERE 절에 AND나 OR 또는 NOT 등을 포함한 불리언 표현식은 물론 실행 순서를 제어하기 위해 괄호를 사용할 수 있다는 점을 설명했다. 그떄 예제로 사용했던 쿼리는 다음과 같다.
SELECT
  gender,
  tripduration
FROM
  `bigquery-public-data`.new_york_citibike.citibike_trips
WHERE
  (tripduration < 600
    AND gender = 'femaie')
  OR gender = 'male'

다음과 같이 불리언 변수와 함께 비교 연산자를 사용해도 된다.

WITH
  example AS (
  SELECT
    NULL AS is_vowel, NULL AS letter, -1 AS position
  UNION ALL SELECT TRUE,'a',1
  UNION ALL SELECT FALSE, 'b',2
  UNION ALL SELECT FALSE,'c',3 
)
SELECT * FROM example WHERE is_vowel != FALSE

그러나 다음 예제처럼 내장 상수와 비교할 때는 IS 연산자를 사용하는 것이 더 간단하다.

WITH
  example AS (
  SELECT
    NULL AS is_vowel, NULL AS letter, -1 AS position
  UNION ALL SELECT TRUE,'a',1
  UNION ALL SELECT FALSE, 'b',2
  UNION ALL SELECT FALSE,'c',3 
)
SELECT * FROM example WHERE is_vowel IS NOT false

이때 두 쿼리의 실행 결과가 다른 것을 알 수 있다. 비교 연산자(=, !=, < 등)는 NULL과 비교하면 NULL을 리턴하지만 IS 연산자는 그렇지 않기 때문이다.


■ 조건식

  • 불리언이 WHERE 절에서만 유용한 것은 아니다. SELECT에서 조건식을 사용하면 쿼리를 단순화할 수 있다. 예를 들어 카탈로그의 품목별로 희망하는 가격 인상율 및 세율을 적용해 최종 판매 가격을 계산해야 한다고 가정해 보자. 이때 카탈로그에서 인상율이나 세율이 누락되어 있으면 기본 인상율이나 세율을 적용하고자 한다. 이런 경우 IF 함수를 사용하면 된다.
WITH catalog AS(
    SELECT 30.0 AS costPrice, 0.15 AS markup, 0.1 AS taxRate
    UNION ALL SELECT NULL, 0.21, 0.15
    UNION ALL SELECT 30.0, NULL, 0.09
    UNION ALL SELECT NULL, NULL, 0.09
    UNION ALL SELECT 30.0, NULL, NULL 
)
SELECT *, ROUND(
    costPrice *
    IF(markup is NULL, 1.05, 1+markup) *
    IF(taxRate IS NULL, 1.10, 1+taxRate), 2) AS salesPrice
FROM catalog

  •  IF 함수의 첫 번째 파라미터는 평가할 조건이다. 조건이 참이면 두 번째 파라미터를 반환하고, 그렇지 않으면 세 번째 파라미터를 반환한다. 이 함수를 SELECT에서 호출했으므로 해당 작업은 각 행마다 실행된다.

■ Coalesce로 Null 값을 깨끗하게 처리하기

  • 단일 값이 누락된 경우에는 보완이 가능하지만, 둘 이상의 값이 누락되어 값을 보완할 수 없다면 어떻게 할까? 다시 말해, 세율만 누락된 경우에는 10%의 세율을 적용하고, 품목의 가격 인상률까지 누락된 경우에는 그렇게 하지 않으려고 한다.
  • 이런 경우 Coalesce 함수를 사용하면 Null이 아닌 값을 얻을 때까지 표현식을 계속 평가할 수 있어 편리하다.
WITH catalog AS(
    SELECT 30.0 AS costPrice, 0.15 AS markup, 0.1 AS taxRate
    UNION ALL SELECT NULL, 0.21, 0.15
    UNION ALL SELECT 30.0, NULL, 0.09
    UNION ALL SELECT NULL, NULL, 0.09
    UNION ALL SELECT 30.0, NULL, NULL 
)
SELECT *, ROUND(COALESCE(
    costPrice * (1+markup) * (1+taxRate),
    costPrice * 1.05 * (1+taxRate),
    costPrice * (1+markup) * 1.10,
    NULL
    ), 2) AS salesPrice
FROM catalog

  • Coalesce는 가능할 때마다 계산을 단락short-circuit 평가한다. 즉, Null이 아닌 결과를 얻은 후에는 식을 평가하지 않는다. 따라서 Coalesce 함수의 마지막 파라미터인 NULL은 필요하지 않지만 그 의도를 더 명확히 표현하기 위한 것이다.
  • 빅쿼리는 입력값이 2개이면 Coalesce보다 간단하게 사용할 수 있는 IFNULL 함수도 지원한다. IFNULL(a,b)는 Coalesce(a,b)와 동일하며 a가 NULL이면 b를 반환한다. 즉 IFNULL(a,b)는 IF(a IS NULL, b, a)와 동일하다.
  • 조건부 표현식에 대한 이 절의 첫 번째 쿼리는 다음처럼 단순하게 표현할 수 있다.
WITH catalog AS(
    SELECT 30.0 AS costPrice, 0.15 AS markup, 0.1 AS taxRate
    UNION ALL SELECT NULL, 0.21, 0.15
    UNION ALL SELECT 30.0, NULL, 0.09
    UNION ALL SELECT NULL, NULL, 0.09
    UNION ALL SELECT 30.0, NULL, NULL 
)
SELECT *, ROUND(
    costPrice * 
    (1 + IFNULL(markup, 0.05)) *
    (1 + IFNULL(taxRate, 0.10))
    ,2) AS salesPrice
FROM catalog


■ 타입 변환과 타입 강제

  • 직원의 휴가 사유를 근무 시간 대신 기록하기 위해 근무 시간을 문자열로 저장하는 예제 데이터셋을 살펴보자.
WITH example AS(
    SELECT 'John' AS employee, 'Paternity Leave' AS hours_worked
    UNION ALL SELECT 'Janaki', '35'
    UNION ALL SELECT 'Jian', 'Vacation'
    UNION ALL SELECT 'Jose', '40'
)
SELECT SUM(hours_worked) FROM example
  •  hours_worked 컬럼이 숫자 타입이 아닌 문자열이므로 쿼리는 작동하지 않는다.
  • 올바른 값을 얻으려면 집계를 수행하기 전에 hours_worked 컬럼을 INT64로 명시적으로 변환해야 한다. 명시적 타입 변환을 캐스팅casting이라고 하며 CAST( )함수를 명시적으로 사용해야 한다. 캐스팅이 실패하면 빅쿼리는 오류를 반환한다. 오류 대신 NULL을 반환하려면 SAFE_CAST를 사용한다. 예를 들어 다음 쿼리는 오류를 발생한다.
SELECT CAST("true" AS bool), CAST("invalid" AS bool)

  • 이제 SAFE_CAST를 사용해 보자.
SELECT CAST("true" AS bool), SAFE_CAST("invalid" AS bool)

  • 임시적 변환을 타입 강제coercion라고 하며, 사용하는 데이터 타입과 필요한 데이터 타입이 다르면 자동으로 타입 강제가 이뤄진다. 예를 들어 FLOAT64가 필요한데 INT64를 사용하면 정수는 부동소수점 숫자로 강제로 변환된다. 빅쿼리가 수행하는 유일한 타입 강제는 INT64FLOAT64NUMERIC으로, NUMERICFLOAT64로 변환하는 것이다. 다른 모든 변환은 명시적으로 CAST를 사용해야 한다.
  • 총 근무 시간을 구하는 문제에서 hours_worked 문자열 컬럼의 값 중에는 'Vacation'처럼 정수로 변환할 수 없는 값도 있으므로 SAFE_CAST를 사용해야 한다.
WITH example AS(
    SELECT 'John' AS employee, 'Paternity Leave' AS hours_worked
    UNION ALL SELECT 'Janaki', '35'
    UNION ALL SELECT 'Jian', 'Vacation'
    UNION ALL SELECT 'Jose', '40'
)
SELECT SUM(SAFE_CAST(hours_worked AS INT64)) FROM example

  • 만약 단순히 스키마 문제로 모든 행의 데이터가 숫자를 표현하는 문자열로 저장된 경우라면, 즉 숫자가 아닌 문자열이나 NULL 값 등이 없다면 간단하게 CAST를 사용할 수 있다.
WITH example AS(
    SELECT 'John' AS employee, '0' AS hours_worked
    UNION ALL SELECT 'Janaki', '35'
    UNION ALL SELECT 'Jian', '0'
    UNION ALL SELECT 'Jose', '40'
)
SELECT SUM(CAST(hours_worked AS INT64)) FROM example


■ 불리언 변환을 피하기 위해 COUNTIF 사용하기

WITH example AS(
    SELECT true AS is_vowel, 'a' AS letter, 1 AS position
    UNION ALL SELECT false, 'b',2
    UNION ALL SELECT false, 'c',3
)
SELECT * FROM example

  • SUM, AVG 등은 불리언 값과는 작동하지 않는다. 따라서 다음과 같이 집계를 수행하기 전에 불리언 값을 INT64로 변환해야 한다.
WITH example AS(
    SELECT true AS is_vowel, 'a' AS letter, 1 AS position
    UNION ALL SELECT false, 'b',2
    UNION ALL SELECT false, 'c',3
)
SELECT SUM(CAST(is_vowel AS INT64)) AS num_vowels FROM example

  • 하지만 가능하면 타입 변환은 피하는 것이 좋다. 이 예제에서는 불리언 값에 IF 문을 사용하는 것이 더 깔끔하다.
WITH example AS(
    SELECT true AS is_vowel, 'a' AS letter, 1 AS position
    UNION ALL SELECT false, 'b',2
    UNION ALL SELECT false, 'c',3
)
SELECT SUM(IF (is_vowel,1,0)) AS num_vowels FROM example

  • 그리고 이보다 더 나은 방법은 COUNTIF를 사용하는 것이다.
WITH example AS(
    SELECT true AS is_vowel, 'a' AS letter, 1 AS position
    UNION ALL SELECT false, 'b',2
    UNION ALL SELECT false, 'c',3
)
SELECT COUNTIF(is_vowel) AS num_vowels FROM example

 

+ Recent posts