case () 사용시“Operator 'getitem'은이 표현식에서 지원되지 않습니다.”오류 해결 방법
Nov 16 2020
다음 SQL을 SQLAlchemy로 변환하려고합니다.
select t1.id, t1.field_A,
max(case when t2.field_B = 1 then t2.field_C end) test_2_field_b_1,
max(case when t2.field_B = 2 then t2.field_C end) test_2_field_b_2
from test_1 t1
inner join test_2 t2 on t2.field_A = t1.field_A
group by t1.id, t1.field_A
내가 가지고있는 것 :
qry = session.query(
Test1.id_,
Test2.field_A,
func.max(case((Test2.field_B.__eq__(1), "Test2.field_C"))).label("test_2_field_b_1"),
func.max(case((Test2.field_B.__eq__(2), "Test2.field_C"))).label("test_2_field_b_2"),
)
qry = qry.select_from(Test1)
qry = qry.join(Test2, Test2.field_A.__eq__(Test1.field_A))
qry = qry.group_by(Test1.id_, Test2.field_A)
하지만 다음과 같은 오류가 발생합니다.
NotImplementedError: Operator 'getitem' is not supported on this expression
라인에서 :
func.max(case((Test2.field_B.__eq__(1), "Test2.field_C"))).label("test_2_field_b_1"),
그래서 너무 많은 코드가 있다고 말하면서 전체 트레이스 백을 게시하지 않을 것입니다!
내가 어디로 잘못 가고 있습니까?
답변
2 snakecharmerb Nov 17 2020 at 01:16
case 는 when 기준 의 목록 을 첫 번째 인수로 취 하므로 적절하게 대괄호를 사용해야합니다.
sa.case([(Model.column == value)])
따라서 코드는 다음과 같아야합니다.
qry = session.query(
Test1.id_,
Test2.field_A,
sa.func.max(sa.case([(Test2.field_B == 1, "Test2.field_C")])).label("test_2_field_b_1"),
sa.func.max(sa.case([(Test2.field_B == 2, "Test2.field_C")])).label("test_2_field_b_2"),
)
qry = qry.select_from(Test1)
qry = qry.join(Test2, Test2.field_A == Test1.field_A)
oskros Nov 16 2020 at 18:21
이것은 귀하의 질문에 직접 대답하지는 않지만 과거에는 SQL 쿼리에 pyodbc 및 pandas를 사용하여 훨씬 더 많은 행운을 얻었으므로 쿼리를 번역 할 필요가 없습니다.
import pandas as pd
import pyodbc
conn = pyodbc.connect("<Insert connection string here>")
sql = """
select t1.id, t1.field_A,
max(case when t2.field_B = 1 then t2.field_C end) test_2_field_b_1,
max(case when t2.field_B = 2 then t2.field_C end) test_2_field_b_2
from test_1 t1
inner join test_2 t2 on t2.field_A = t1.field_A
group by t1.id, t1.field_A
"""
df = pd.read_sql(sql, conn)