Pull to refresh

Comments 29

Для начала подключимся к постгресу и получим результат запроса

Для PostgreSQL есть расширение PL/Python — Python Procedural Language, позволяет писать код на Python непосредственно в теле функций.
ИМХО хранить и сопровождать логику в объектах БД намного проще.
Да, Вы правы, есть. Но для PostgreSQL 9.2 родным является python 3, python 2.7 к сожалению завести не смог. На счет сопровождения логики в БД в моем случае не согласен — для меня не очень понятно как версионировать и дебажить.
Дебажить — RAISE NOTICE, RAISE EXCEPTION. Версионировать — DDL объектов в файлах. А дальше как угодно — хоть систему контроля версий.

Просто если у вас пара-тройка клиентов — ваш подход оправдан, а если много — то не очень.

А за некоторые фишки Python'а спасибо, пригодится. Я на нём мало писал, в основном простенькие скрипты (намного удобнее, а главное — быстрее, чем на bash'е)
А как например просмотреть структуру объекта? Какие у него есть методы и свойства? Автодополнения я тоже понимаю, что нету.
А, ну тут не знаю. От среды разработки зависит. С Postgres работаю либо непосредственно в pgAdmin, либо локально любым текстовым редактором, код на plpgsql, математики мало, в основном бизнес-логика, но её очень много :)
А что посоветовать для Python'а не знаю…
Я как раз таки про pgAdmin и говорил, что там этого ничего не будет.
Так никто не мешает отладить ваш класс локально, затем скопипастить его в заготовку функции в БД. Или плагин какой для редактора написать (для Sblime Text например, плагины на python'е, как раз для вас :) )
Главное определиться, найти инструмент не проблема.
Мне кажется такой набор инструментов не ведет к повышению скорости разработки :)
А почему не одним проходом с простым case (хотя тут даже видно простое округление до десятка) и группировкой?
Показываю усложненным примером с ntile для старых версий оракла(в последних есть pivot/unpivot), который вроде должен пойти и для PostgreSQL.
Например, есть таблица:
SQL# select salary,department_id from hr.employees;

    SALARY DEPARTMENT_ID
---------- -------------
      2600            50
      2600            50
.......{skipped}..........
      4400            10

Код будет вроде такого:

SQL# select
  2    t1.n
  3    ,min(salary)
  4    ,max(salary)
  5    ,count(case when department_id between 1  and 40 then 1 end) d_1_40
  6    ,count(case when department_id between 41 and 70 then 1 end) d_41_70
  7    ,count(case when department_id between 71 and 120 then 1 end) d_71_110
  8  from (
  9        select salary
 10              ,department_id
 11              ,ntile(10)over(order by salary) n
 12        from hr.employees
 13       ) t1
 14  group by t1.n
 15  /

         N MIN(SALARY) MAX(SALARY)     D_1_40    D_41_70   D_71_110
---------- ----------- ----------- ---------- ---------- ----------
         1        2100        2500          1         10          0
         6        6400        7400          1          1          8
         2        2600        2900          3          8          0
         4        3200        4100          0         11          0
         5        4200        6200          2          6          3
         8        8400        9500          0          1          9
         3        2900        3200          1         10          0
         7        7500        8300          0          3          8
         9        9600       11000          1          1          8
        10       11500       24000          1          0          9

10 rows selected.
Спасибо. Очень полезно.
Правда есть некоторые сложности ( например со скоростью, как написано в статье — все понятно, там наименьшее значение — 0, наибольшее — как получится, а вот если есть уровень, то градации определяются от среднего, то есть мне нужно взять ряд, вычесть у него среднее, определить минимум и максимум, и только потом строить все это дело — получается раздуто для SQL)
В postreSQL нет аналогов оракловых аналитических оконных функций?
В оракле это легко было бы: max() over(),min() over(),avg() over()
Если честно, я не знаю про аналитические оконные функции. Я погуглил увидел слово OLAP. На сколько мне известно, с этим у PostgreSQL не очень (мнение виденное в комментариях на хабре, лично не сталкивался и говорить точно не могу.).

В ключе моей задачи сейчас объясню:
получим ряд минимальных и максимальных значений для ряда, у которого вычтено среднее, и округлим их до ближайшей кратности пятерки.
select round(min(100*(level - (select avg(level) from tbldatatest))/5))*5,round(max(100*(level - (select avg(level) from tbldatatest))/5))*5 from tbldatatest;

получается от -10 до 70, и разбивать этот диапазон уже на градации по 5. А дальше для каждой градации делать select Case. Я это подразумевал под раздутостью.
Если Вы знаете, как с помощью SQL быстро квантовать колонки, я был бы счастлив, если бы Вы этим знанием со мной поделились.
да точно так же. внутри можно это получить как:
 , round((min(level)over() - avg(level) over())*100/5)*5
 , round((max(level)over() - avg(level) over())*100/5)*5
я так понял, что
 , round((min(level)over() - avg(level) over())*100/5)*5

равносильно
round(min(100*(level - (select avg(level) from tbldatatest))/5))*5

просто запись короче, а результат тот же. Вопрос — как потом полученный результат
level - (select avg(level) from tbldatatest)

бить по категориям полученных из мин макс без кучи CASE.

ну можно джойном с пивот таблицей. А отличие в другом — то что я показал можно легко выполнять в инлайн вью, т.е. прямо в запросе. Соответственно все можно решить одним запросом с однократным чтением таблицы
Все, теперь понял, Вы радеете за нагрузку. Спасибо за совет.
Интересно, спасибо.
А R не пробовали? Недавно с ним познакомился — выглядит очень похоже на вашу задачу и решение.
Pandas по вашему описанию так вообще один в один R на питоне.
Просто вся экосистема на Python. Есть несколько вещей на R, но их не много. Для себя пока не нашел задач, которые быстрее бы решались в R, чем в python.И да, в Pandas есть встроенные Rpy. И вот тоже интересно сравнение Pandas и Rpy.
*Сравнение Pandas и R конечно же
Что-то по ссылке на сравнение почти ничего нет.
Там даются библиотеки по R project с которыми можно сравнивать функциональность. Но в целом да, ссылок нет, но гуглить можно по ключевым словам.
Для больших объемов данных уже лежащих в базе есть такое правило — все что можно, нужно делать в SQL. У вас там мелочевка несколько десятков тысяч записей, так что может быть удобнее написать на том языке, который вы лучше знаете. Если данных много, то возникают узкие места либо при передаче данных либо при запросах к БД, либо просто в поддержке — люди еще и питон должны знать.
Функции pivot в стандарте SQL нету, я знаю только в MSSQL расширении. Я обычно создаю производную колонки по которой потом можно групировать (т.е. то, что потом будет по горизонтальной оси), а потом вытягиваю данные в Excel через ODBC прямо в pivot table. Так не нужно ничего программировать нового. Ну или вот в Qlikview, если данных много.
Про большие объемы вы правы — плюс тут еще для меня очень важна скорость разработки, потому что новая волна отчетов не за горами.

Вытягивать в сторонние приложения — это тоже нужно работать руками потом. Как в Qlikview «прописывать синтаксис» и тп. Все хорошо когда есть на это целый data processing отдел. А когда его нету и набор таблиц пока маленький, все данные одинаковые, тогда хочется, что бы все было готово сразу.
Qlikview не нужно ничего прописывать можно просто select * from сказать и все.
Ну дальше же нужно как-то таблицы и графики настраивать?
Функции pivot в стандарте SQL нету, я знаю только в MSSQL расширении

И в оракле тоже есть
Sign up to leave a comment.

Articles