링크한 글에서는 MAX()를 사용하고 있는데 경우에 따라 SUM()이 필요할 수도 있을 것 같다.
SQLite 같은 프로그램은 @sql같은 것을 지원하지 않지만, query를 여러번에 나누어서 수행하면 된다.
아래 코드는 어떤 Django app에서 코드의 일부를 가져온 것이다. 긴 코드를 조금이라도 줄이기 위해 원래 코드의 일부를 삭제했고 테이블 이름이나 컬럼 이름도 간단하게 고쳤다. 그렇기 때문에 아래 코드가 실행이 안 될 수도 있다. 먼저, 아래 코드와 관련된 테이블 구조를 간단하게 설명하겠다.
- item table은 모든 item을 담고 있는 테이블이다. 각 item의 이름과 가격 등이 저장되어 있다.
- enabled_item_for_Z table은 어떤 Z에서 사용할 수 있는 item을 담고 있는 테이블이다. 이 테이블은 Z와 item을 foreign key로 가지고, 가격 등의 정보가 저장하고 있다. 가격을 중복으로 저장하는 이유는 Z에 따라 가격이 달라지는 상황을 고려했기 때문이다.
- request table은 user가 어떤 enabled_item_for_Z를 몇 개 신청했는지 저장하는 테이블이다. 이 테이블은 enabled_item_for_Z와 user를 foreign key로 가지고, 신청 수량 등을 저장하고 있다.
def some_func(request, myid): #### ... #### raw db connection cursor = connection.cursor() #### get available item list query_str_item = ( 'SELECT "item"."id", "item"."name"' ' FROM "item"' ' INNER JOIN "enabled_item_for_Z" ON ' ' ("item"."id"' ' = "enabled_item_for_Z"."item_id")' ' WHERE "enabled_item_for_Z"."Z_id" = %s' ' ORDER BY "item"."id"' ) cursor.execute(query_str_item, [myid]) capsule_list = cursor.fetchall() #### make query string for selection aggregate_str = ( '"SUM(CASE WHEN item_id=" || item.id' ' || " THEN request.{0}' ' ELSE 0 END) AS {1}"' ' || item.id AS {2}' ) from_str = ( ' FROM "item"' ' INNER JOIN "enabled_item_for_Z" ON ' ' ("item"."id"' ' = "enabled_item_for_Z"."item_id")' ' WHERE "enabled_item_for_Z"."Z_id" = %s' ' ORDER BY "item"."id"' ) inner_str = 'SELECT '\ + aggregate_str.format('quantity', 'qty_', 'c')\ + from_str query_str_0 = 'SELECT'\ + ' group_concat(c, ", ") AS gc'\ + ' FROM (' + inner_str + ')' cursor.execute(query_str_0, [myid]) select_str = cursor.fetchall()[0][0] if select_str is None: select_str = 'COUNT(*)' #### get pivot table query_str_1 = 'SELECT auth_user.username' query_str_1 += ( ', SUM(item_request.quantity) AS SUM' ', SUM(enabled_item_for_Z.price' ' * item_request.quantity) AS GT' ) query_str_1 += ', ' + select_str query_str_1 += ( ' FROM "item_request"' ' INNER JOIN "enabled_item_for_Z" ON ' ' ("item_request"."enabled_item_for_Z_id"' ' = "enabled_item_for_Z"."id")' ' INNER JOIN "auth_user" ON' ' ("item_request"."user_id" = "auth_user"."id")' ' WHERE "enabled_item_for_Z"."Z_id" = %s' ' GROUP BY item_request.user_id' ) cursor.execute(query_str_1, [myid]) request_list = cursor.fetchall() #### get total row total_row = [sum(x) if i > 0 else 'Total' for i, x in enumerate(zip(*request_list))] #### ...
댓글 없음:
댓글 쓰기