저번 포스팅에서는 파이썬 상에서 AWS Redshift를 연결하여, 직접 Jupyter Notebook 상에서 쿼리를 날리는 방법에 대해 알아보았습니다. (이전 포스팅 바로가기)
그런데 궁금증이 생깁니다. 파이썬에서 쿼리를 날릴 땐 쿼리문에 반드시 따옴표 3개를 써서 주석 처리를 해야 하는데,
그럼 파이썬 상에선 이것이 주석으로 인식됩니다.
하지만 쿼리상에서 어떤 조건을 input으로 즉, 파라미터(parameter)로 넣고자 할 때는 어떻게 해야 할까요?
결론부터 말하자면 format 메서드를 사용해주면 됩니다.
앞의 포스팅에서는 다음의 쿼리를 실행했습니다.
예를 들어, 저는 주간 매출 랭킹 10위 안에 드는 인기 상품만 뽑아보고자 합니다. 상품 테이블은 product에, 매출정보 테이블은 sale_table에 있다고 해봅시다. (가상의 테이블입니다)
그럼 상품과 매출정보 테이블을 연결하고, 매출액 순으로 상품을 정렬한 후 10위까지만 뽑아보면 되겠죠? 예시로 쿼리를 만들어보겠습니다.
# Query a table using the Cursor
cursor.execute("""
with everly as (
a.product_code, a.product_name, a.product_price,
b.sales_amt, b.datetime
from product a
join sale_table b
where a.prodcut_code = b.prodcut_code
and b.datetime between (current_date - '7 day'::interval and current_date)
)
select product_code, product_name,
product_price, sum(sales_amt) as sum_sales_amt
from everly
group by 1, 2, 3
order by 4 desc
limit 10;
""")
conn.commit()
# Print as a dataframe
df: pd.DataFrame = cursor.fetch_dataframe()
이렇게 쿼리를 날려봤더니, 상품이 너무 많이 나옵니다.
그래서 저는 "특정 브랜드"와 "특정 카테고리"를 조건으로 하여, 각 조건별로 결과를 따로 뽑고 싶습니다.
→ 이 "특정 브랜드"와 "특정 카테고리"를 사용자가 직접 input으로 넣고자 하는 함수를 만들어봅시다!
Python SQL Formatting
먼저 쿼리문을 수정하면 이렇게 쓸 수 있습니다.
sql = """
with everly as (
a.product_code, a.product_name, a.product_price,
b.sales_amt, b.datetime
from product a
join sale_table b
where a.prodcut_code = b.prodcut_code
and b.datetime between (current_date - '7 day'::interval and current_date)
and a.brand_name = {0}
and a.category_name = {1}
)
select product_code, product_name,
product_price, sum(sales_amt) as sum_sales_amt
from everly
group by 1, 2, 3
order by 4 desc
limit 10;
"""
with절을 보시면 where 조건절에 brand_name과 category_name이라는 새로운 절이 추가되었습니다.
파이썬 포맷팅(python formatting)을 하기 위해선 위의 sql 변수에 format 메서드를 사용해서 cursor를 execute합니다.
cursor.execute(sql.format('brand_name_input', 'category_name_input'))
conn.commit()
df: pd.DataFrame = cursor.fetch_dataframe()
위처럼 원하는 브랜드명과 카테고리명을 직접 써서 실행하면, 원하는 df가 출력됩니다.
예를 들어, Shoes 카테고리의 Nike 제품만 보고자 한다면 이렇게 쓰면 됩니다.
cursor.execute(sql.format('Shoes', 'Nike'))
※ (주의) 이렇게 해서 에러가 나는 경우가 있습니다. 이는 DB에서 'Shoes', 'Nike' 이런 애들이 전부 문자열이기 때문인데요!
파이썬 상에서는 쿼리문을 따옴표 3개로 감싸므로 주석처럼 처리된다고 했었죠?
그래서 따옴표 1개로만 써주는 게 아니라, 따옴표 2개로 감싸주면 해결됩니다.
cursor.execute(sql.format("'Shoes'", "'Nike'"))
함수화
위의 과정을 활용해서, 브랜드명과 카테고리명을 input으로 받고, 결과는 데이터프레임이 출력되도록 함수로 만들어봅시다.
def extract_from_db(brand_name_input, category_name_input):
# 계정 연결
import redshift_connector
conn = redshift_connector.connect(
host='examplecluster.abc123xyz789.us-west-1.redshift.amazonaws.com',
database='dev',
user='awsuser',
password='my_password')
cursor: redshift_connector.Cursor = conn.cursor()
# Query
sql = """
with everly as (
a.product_code, a.product_name, a.product_price,
b.sales_amt, b.datetime
from product a
join sale_table b
where a.prodcut_code = b.prodcut_code
and b.datetime between (current_date - '7 day'::interval and current_date)
and a.brand_name = {0}
and a.category_name = {1}
)
select product_code, product_name,
product_price, sum(sales_amt) as sum_sales_amt
from everly
group by 1, 2, 3
order by 4 desc
limit 10;
"""
# input 정보 실행
cursor.execute(sql.format(brand_name_input, category_name_input))
conn.commit()
# output
df: pd.DataFrame = cursor.fetch_dataframe()
return df
완성!
결과가 잘 나오는지는 직접 함수를 실행해 확인해보세요 :)
'Skillset > SQL' 카테고리의 다른 글
[Redshift] DBeaver에서 프로시저 만들기 (0) | 2024.02.29 |
---|---|
[Python, Redshift] 파이썬에 AWS Redshift 연결하여 사용하는 방법 (1) | 2022.09.19 |
[MySQL] 문자열에서 0 제거하기 (REPLACE) (0) | 2022.08.12 |
SQL로 깔끔한 문장 출력하기 (CONCAT 활용) (0) | 2022.08.10 |
SQL 중첩된 CASE WHEN 구문 활용: 삼각형의 타입 구분하기 (0) | 2022.08.09 |