Как автоматизировать SQL код, используя Python эффективным способом - PullRequest
1 голос
/ 02 марта 2020

У меня есть sql код, который выглядит следующим образом: База данных: RedShift

WITH
X as
(  
 SELECT  distinct pn , pg , ic, sr  , cm, fq , m1  , m2  , m3  , m4
 FROM table1  ORDER BY 1,2,3
),

table2 AS
 (
   Select g,p,t , avg(ss) as ss , avg(ce) as ce , sum(av) as ps
  from
 (
select distinct ic AS g , pn AS p , cm AS t , ss , cast((sum_m1/nullif(sum_m2,0)) as decimal(3,2)) as 
 ce , av
from
(
  select *
  , cast((sum(m3) over (partition by ic, pn,cm)) as decimal) as ss
  , sum(m1) over (partition by ic, pn,cm) as sum_m1
  , sum(m2) over (partition by ic, pn,cm) as sum_m2
  , cast((avg(m2) over (partition by ic, pn,cm)) as decimal) as av
  from X
  ORDER BY 1,2,3
)
order by 1,2,3
 )
 where ss is not null
  group by 1,2,3
  order by 1,2,3
  )

Группа по значению g,p,t меняется каждый раз, поэтому она создает таблицу для каждой новой комбинации g,p,t значений.

Один из способов автоматизации - сбросить этот sql код в Python, что может быть неэффективно. Вот мой подход -> Я заменяю все значения в списке на {} фигурные скобки. Пример говорит:

Я сохраняю все возможные группы по значениям в списке.

G = [g1, g2, g3]

P = [p1, p2, p3]

T = [t1, t2, t3]

Подключение к базе данных:

   c= psycopg2.connect(database=db,host=host,port=port,user=user,password=password,sslmode='require')
   data2={}

   for g in G:

     for p in P:

        for t in T:
           sqlstr=( """ WITH
                            X as
                          (  
                 SELECT  distinct pn , pg , ic, sr  , cm, fq , m1  , m2  , m3  , m4
              FROM table1  ORDER BY 1,2,3
                        ),

                  table2 AS
              Select {},{},{} , avg(ss) as ss , avg(ce) as ce , sum(av) as ps
                             from
                         (
                    select distinct ic AS g , pn AS p , cm AS t , ss , cast((sum_m1/nullif(sum_m2,0)) as decimal(3,2)) as 
                      ce , av
                          from
                  (
                       select *
               , cast((sum(m3) over (partition by ic, pn,cm)) as decimal) as ss
                , sum(m1) over (partition by ic, pn,cm) as sum_m1
               , sum(m2) over (partition by ic, pn,cm) as sum_m2
               , cast((avg(m2) over (partition by ic, pn,cm)) as decimal) as av
                      from X
                     ORDER BY 1,2,3
                       )
                   order by 1,2,3
                    )
                 where ss is not null
                   group by 1,2,3
                   order by 1,2,3
                    ), select * from table2 """).format(g,p,t)
  data2[g+"_"+p+"_"+t] = pd.read_sql_query(sqlstr, c)

Есть ли лучший способ передачи параметров, как в приведенной выше кодовой последовательности {}, следует сохранить передать параметры в порядке ??

Можем ли мы использовать какой-то другой подход, кроме SQL? В питоне c кстати?

...