Ir para o conteúdo
ou

Software livre Brasil

Tela cheia
 Feed RSS

SAVEPOINT

27 de Maio de 2009, 0:00 , por Software Livre Brasil - | Ninguém está seguindo este artigo ainda.

Janeiro

4 de Janeiro de 2011, 0:00, por Software Livre Brasil - 0sem comentários ainda

Janeiro é um mês estranho.

  • Depois da maratona de amigo-secreto, amigo-da-onça, amigo-ladrão e outras invenções para ajudar os donos de lojas de R$1,99;
  • Depois de todas a comemorações e bebemorações com os amigos, das festas promovidas pelo patrão, jantares formais e informais;
  • Depois de rever a família, relembrar todas as intrigas que os parentes conseguem carregar por meses a fio esperando aquele momento em que todos estão lá reunidos e bêbados esperando o momento da lavagem de roupa suja e das revelações perturbadoras;
  • Depois de desejar felicidades, fazer votos solidários, mandar o KIT FELICIDADES, entupir as caixas de mensagens com spans para amigos, inimigos, desconhecidos;
  • Depois de contabilizar todas as gafes, promessas não cumpridas, dívidas não pagas, amores perdidos, oportunidades que escorregaram e frustrações acumuladas;
  • Depois de aturar zilhões de especiais de natal, shows do Roberto Carlos, Xuxa e outras bizarrices que as TVs, Internet e e camelôs insistem em irradiar pelo spectro, cabo, DVDs, Blue-Ray, pen-drive e o que mais inventarem
  • Depois de torrar até o último centavo do 13º (para quem ainda sabe o que é isso), bonus, cartão de crédito, cheque especial, agiotas e tudo o mais que lhe permita fazer um monte de parcelas em lojas entupidas de gente;
  • Depois de fazer promessas, traçar planos e estabelecer metas para o ano seguinte;
  • Depois de se matar no trampo para gastar todo o orçamento que seu chefe esqueceu de gastar no ano inteiro;
  • Depois de fazer todas as migrações, implantar todos os sistemas e tudo o mais que é necessário para que os outros consigam atingir suas metas que eles deixaram para lá durante 11 meses;
  • Depois de enfrentar um trânsito descomunal, filas intermináveis para comprar um simples perú e chuvas torrenciais na hora do rush;
  • Depois de se penitenciar/congratular/regozijar, pelo nascimento/morte/chegada/foo_event de alguma figura proeminente de alguma religião bar, lembrar e ser lembrado por todos à sua volta disso;

Bom depois de sobreviver a tantas provações, excessos e eventos cataclísmicos, tudo isso, chega o porre homérico do ano novo. Janeiro chega enfim como uma bonança há tempos esperada.

Enquanto muitos lotam as praias, hoteis, pousadas, castelos europeus, campings e outras acomodações, muitos continuam a trabalhar, mas não normalmente:

  • O trânsito se torna suportável, mesmo após as chuvas torrencias de verão;
  • Ninguém quer fazer migrações, implantações ou grandes mudanças nesta época;
  • O número de usuários cai incrivelmente, pois a maioria está lotando as praias, hotéis….
  • Os restaurantes estão mais vazios, as filas nos bancos e lotéricas estão menores;
  • A banda da Internet (pelo menos no trabalho) está uma maravilha!
  • Os radares continuam multando normalmente e aqueles que se empolgam com a diminuição nos engarrafamentos e não se lembrar que existem limites de velocidade…
  • O tédio toma conta dos filhos que não foram viajar e atazanam a vida dos pais que mesmo com pouco trabalho e com pouco trânsito continuam chegando cansados do trabalho pensando naquela cerveja na praia…
  • A televisão começa a parar de passar retrospectivas, especiais de natal, reprises e coisa e tal e volta a exibir o mesmo lixo habitual;

Então janeiro é este mês mágico onde a insanidade de dezembro se encerra sem que no entanto as promessas de ano-novo se iniciem, uma vez que isso só passa a valer depois do carnaval. É aquele período mágico onde a tendinite acumulada em dezembro ainda o assombra, mas já permite que você abra a porta de casa sem arder infernalmente. É uma época em que alguns pais corajosos se aventuram a levar seus filhos em parques de diversões abarrotados de crianças com insolação e encharcadas de chuva ao mesmo tempo, lutando para conseguir ir em mais de um brinquedo no mesmo dia. Ok, eu confesso, levei meus filhos no tal do Hopi Hari tempos atrás e descobri que isso é tão idiota quanto querer levar a namorada/esposa/amante/secretária no motel no dia dos namorados/secretária sem reserva.

E cá estamos nós, tirando poeira do blog em pleno horário de expediente, lendo os quadrinhos excepcionais do André Dahmer na internet, lendo mais um livro do Douglas Adams na hora do almoço, marcando todos os seus Feeds/mails/tarefas de 2010/whatever como lidos e mergulhando naquela sensação pinkfloydiana de “Confortably Numb“.

Não é a euforia que poderia ser numa praia tomando todas com os amigos. Não é a calma de estar em casa assistindo uma eterna sessão da tarde. Nem tão refivigorante como um retiro nas cachoeiras de Lumiar. Mas é esse momento de suspensão onde nos permitimos um pouco de ócio produtivo, um pouco de delírio, um pouco de calma e um monte de dívidas para pagar.

Janeiro para mim é isso. De longe o pior mês do ano para se tirar férias, pelo simples motivo de todos quererem justamente isso. O melhor mês para implantar coisas que seu chefe boicota há tempos (afinal ele está de férias…). O melhor mês para ler coisas diferentes e ver filmes bizarros. E deixem janeiro passar sem pressa, como um domingo preguiçoso sem louça para lavar.



Habilitar e desabilitar todos os JOBS do Oracle

10 de Dezembro de 2010, 0:00, por Software Livre Brasil - 0sem comentários ainda

Ao migrar uma base via DUMP (seja com expdp/impdp ou exp/imp) ou realizar algumas manutenções como atualizações de aplicação, é sempre uma boa idéia parar todos os JOBS que estão rodando no banco antes de começar o trabalho. Não basta matar os processos ativos(ou mesmo reiniciar a base), você tem de cuidar para que os JOBs não sejam iniciados no meio do processo e este é um erro muito comum.

Para facilitar este trabalho criei o pequeno script abaixo que cria dois arquivos, um para desabilitar os JOBs e outro para habilitar novamente. Outro erro comum é desabilitar os JOBs e depois não saber quais estavam ativos antes, na hora de habilita-los.

Um último adendo, aqui eu estou utilizando o DBMS_IJOB (que não está bem documentado, mas permite trabalhar com jobs de outros usuários) e o DBMS_SCHEDULER para aqueles que utilizam este recurso introduzido no 10g.

sqlplus -s / AS sysdba <<EOF
SET heading off
SET trimspool ON
SET term off
SET echo off
SET feed off
 
SPOOL 'jobs_to_broken.sql'
SELECT 'EXEC dbms_ijob.broken(' || job || ',TRUE);' 
    FROM dba_jobs 
    WHERE broken = 'N';
 
SELECT 'EXEC dbms_scheduler.disable (''' || owner || '.' || job_name || ''');' 
    FROM dba_scheduler_jobs 
    WHERE enabled = 'TRUE'
    ORDER BY owner, job_name;
 
SPOOL OFF
SPOOL 'jobs_to_run.sql'
SELECT 'EXEC dbms_ijob.broken(' || job || ',FALSE);' 
    FROM dba_jobs 
    WHERE broken = 'N';
 
SELECT 'EXEC dbms_scheduler.enable (''' || owner || '.' || job_name || ''');' 
    FROM dba_scheduler_jobs 
    WHERE enabled = 'TRUE'
    ORDER BY owner, job_name;
SPOOL OFF
-- rodar '@jobs_to_broken' para desabilitar os JOBs'
-- rodar '@jobs_to_run' para restaurar os JOBs
EOF


Brincando com funções de janelas (Window Functions)

26 de Outubro de 2010, 0:00, por Software Livre Brasil - 0sem comentários ainda

<pre lang=”sql”>Tempos atrás me deparei com um problema que era criar uma função para gerar uma CURVA ABC. Eu não tinha a menor idéia do que ser tratava, mas resumindo, uma Curva ABC é uma separação entre faixas de valores, como os 20% mais ricos e o 20% mais pobres. Se quiser mais detalhes, veja a definição do Wikipédia. Apesar do conceito ser simples, fazer isso com SQL convencional não é. E quem me conhece, sabe que eu só utilizo PL no banco de dados, quando é absolutamente necessário. O motivo é simples, o PL não deixa muita margem para o otimizador do banco de dados encontrar a melhor forma de agrupar os dados. E eu sei que o otimizador é muito mais inteligente que eu.

Bom, resumindo a história, eu precisei lançar mão das novas funções de janela, incorporadas na versão 8.4 do PostgreSQL. Para exemplificar aqui, vou utilizar uma base de exemplo conhecida de todos, o PAGILA. Eu tentei o DELLSTORE, mas os dados não apareceram tão bem distribuídos para efeito de visualização.

Bom, depois de criar uma base e importar os dados do PAGILA, eu criei uma visão para facilitar a minha vida e simplificar a análise, deixando de lado detalhes desnecessários:

CREATE OR REPLACE VIEW sales_pgday AS
    SELECT
        f.title,
        c.name AS category,
        sum(p.amount) AS total_sales
        FROM
            (((((payment p JOIN rental r ON ((p.rental_id = r.rental_id)))
                JOIN inventory i ON ((r.inventory_id = i.inventory_id)))
                JOIN film f ON ((i.film_id = f.film_id)))
                JOIN film_category fc ON ((f.film_id = fc.film_id)))
                JOIN category c ON ((fc.category_id = c.category_id)))
        GROUP BY c.name, f.title
    ;

Com um select você verá os dados mais ou menos assim:

           title            |  category   | total_sales
-----------------------------+-------------+-------------
 AMADEUS HOLY                | Action      |       33.79
 AMERICAN CIRCUS             | Action      |      167.78
 ANTITRUST TOMATOES          | Action      |       37.90
 BAREFOOT MANCHURIAN         | Action      |       66.82
 BERETS AGENT                | Action      |       78.78
 BRIDE INTRIGUE              | Action      |       21.81
 BULL SHAWSHANK              | Action      |       21.84
 CADDYSHACK JEDI             | Action      |       51.84
 CAMPUS REMEMBER             | Action      |       90.81
 CASUALTIES ENCINO           | Action      |       72.91
 CELEBRITY HORN              | Action      |       32.76
 CLUELESS BUCKET             | Action      |      112.75
 CROW GREASE                 | Action      |       18.88
 DANCES NONE                 | Action      |       31.86
 DARKO DORADO                | Action      |       82.89
 DARN FORRESTER              | Action      |       93.82
 DEVIL DESIRE                | Action      |       83.85
 DRAGON SQUAD                | Action      |       27.89
 DREAM PICKUP                | Action      |       81.78
 DRIFTER COMMANDMENTS        | Action      |      141.76
...

O primeiro passo para calcular a curva ABC sobre as vendas de cada filme, para cada categoria de filme (os filmes mais vendidos e os menos vendidos em cada categoria) é calcular o total de vendas. Uma vez que queremos os 20% mais vendidos e os 20% menos vendidos, precisamos do total (100%) para calcular a porcentagem:

SELECT category, sum(total_sales)
    FROM sales_pgday
    GROUP BY category;

E assim teremos:

  category   |   sum
-------------+---------
 Action      | 4375.85
 Animation   | 4656.30
 Children    | 3655.55
 Classics    | 3639.59
 Comedy      | 4383.58
 Documentary | 4217.52
 Drama       | 4587.39
 Family      | 4226.07
 Foreign     | 4270.67
 Games       | 4281.33
 Horror      | 3722.54
 Music       | 3417.72
 New         | 4361.57
 Sci-Fi      | 4756.98
 Sports      | 5314.21
 Travel      | 3549.64
(16 linhas)

Agora vejamos uma função de janela em ação aqui. Ainda não é a que vamos utilizar, é apenas um exemplo:

SELECT
    title,
    category,
    total_sales,
    rank() OVER (ORDER BY total_sales DESC) AS rank
FROM sales_pgday;

Agora vejamos o resultado:

            title            |  category   | total_sales | rank
-----------------------------+-------------+-------------+------
 TELEGRAPH VOYAGE            | Music       |      231.73 |    1
 WIFE TURN                   | Documentary |      223.69 |    2
 ZORRO ARK                   | Comedy      |      214.69 |    3
 GOODFELLAS SALUTE           | Sci-Fi      |      209.69 |    4
 SATURDAY LAMBS              | Sports      |      204.72 |    5
 TITANS JERK                 | Sci-Fi      |      201.71 |    6
 TORQUE BOUND                | Drama       |      198.72 |    7
 HARRY IDAHO                 | Drama       |      195.70 |    8
 INNOCENT USUAL              | Foreign     |      191.74 |    9
 HUSTLER PARTY               | Comedy      |      190.78 |   10
 PELICAN COMFORTS            | Documentary |      188.74 |   11
 CAT CONEHEADS               | Comedy      |      181.70 |   12
 ENEMY ODDS                  | Music       |      180.71 |   13
 BUCKET BROTHERHOOD          | Travel      |      180.66 |   14
 RANGE MOONWALKER            | Family      |      179.73 |   15
 MASSACRE USUAL              | Games       |      179.70 |   16
 VIDEOTAPE ARSENIC           | Games       |      178.71 |   17
 DOGMA FAMILY                | Animation   |      178.70 |   18
 APACHE DIVINE               | Family      |      178.69 |   19
 VELVET TERMINATOR           | Comedy      |      177.74 |   20
...

Agora vamos olhar com calma os dados (tirei aqui apenas as 20 primeiras linhas) e a parte do SELECT que diz:

rank() OVER (ORDER BY total_sales DESC) AS rank

Veja, o campo está utilizando a função RANK, sobre uma janela de dados ordenados pelo total de vendas. O campo RANK simplesmente diz qual é mais significativo, sobre a amostra (OVER) determinada. Agora queremos saber quais são os mais vendidos por categoria. O curioso é que ao invés de utilizar o GROUP BY que afetaria todas as colunas, vamos utilizar o PARTITION BY dentro da definição da janela, assim, isto afetará apenas a nossa última coluna:

SELECT
    title,
    category,
    total_sales,
    rank() OVER (PARTITION BY category ORDER BY total_sales DESC) AS rank
FROM sales_pgday;

Assim teremos:

            title            |  category   | total_sales | rank
-----------------------------+-------------+-------------+------
 FOOL MOCKINGBIRD            | Action      |      175.77 |    1
 AMERICAN CIRCUS             | Action      |      167.78 |    2
 STAGECOACH ARMAGEDDON       | Action      |      154.74 |    3
 EASY GLADIATOR              | Action      |      150.77 |    4
 MINDS TRUMAN                | Action      |      149.80 |    5
 KISSING DOLLS               | Action      |      147.80 |    6
 TRIP NEWTON                 | Action      |      145.72 |    7
 DRIFTER COMMANDMENTS        | Action      |      141.76 |    8
 SUSPECTS QUILLS             | Action      |      133.70 |    9
 WATERFRONT DELIVERANCE      | Action      |      121.83 |   10
...
 DRAGON SQUAD                | Action      |       27.89 |   56
 BULL SHAWSHANK              | Action      |       21.84 |   57
 BRIDE INTRIGUE              | Action      |       21.81 |   58
 CROW GREASE                 | Action      |       18.88 |   59
 LAWRENCE LOVE               | Action      |       15.87 |   60
 MONTEZUMA COMMAND           | Action      |       11.91 |   61
 DOGMA FAMILY                | Animation   |      178.70 |    1
 SUNRISE LEAGUE              | Animation   |      170.76 |    2
 TITANIC BOONDOCK            | Animation   |      154.77 |    3
 FORRESTER COMANCHEROS       | Animation   |      146.73 |    4
 FALCON VOLUME               | Animation   |      127.77 |    5
...

Notem que agora o rank é realizado para cada categoria, o rank é ordenado pelas vendas. Vale a pena executar o SQL no seu computador para verificar os dados com mais calma.

Bom, mas eu quero saber dos 20% mais vendidos. O problema aqui é que você precisaria ir somando o total de vendas de cada produto até chegar em 20% do total. Ocorre que você pode utilizar as funções de agregação como SUM, COUNT e outras junto com a sua janela. Vejamos como isso funciona:

SELECT
    title,
    category,
    total_sales,
    rank() OVER (PARTITION BY category ORDER BY total_sales DESC) AS rank,
    sum(total_sales) OVER (PARTITION BY category ORDER BY total_sales DESC) AS sum
FROM sales_pgday;

E teremos os seguintes dados:

            title            |  category   | total_sales | rank |   sum
-----------------------------+-------------+-------------+------+---------
 FOOL MOCKINGBIRD            | Action      |      175.77 |    1 |  175.77
 AMERICAN CIRCUS             | Action      |      167.78 |    2 |  343.55
 STAGECOACH ARMAGEDDON       | Action      |      154.74 |    3 |  498.29
 EASY GLADIATOR              | Action      |      150.77 |    4 |  649.06
 MINDS TRUMAN                | Action      |      149.80 |    5 |  798.86
 KISSING DOLLS               | Action      |      147.80 |    6 |  946.66
 TRIP NEWTON                 | Action      |      145.72 |    7 | 1092.38
 DRIFTER COMMANDMENTS        | Action      |      141.76 |    8 | 1234.14
 SUSPECTS QUILLS             | Action      |      133.70 |    9 | 1367.84
 WATERFRONT DELIVERANCE      | Action      |      121.83 |   10 | 1489.67
 TRUMAN CRAZY                | Action      |      121.77 |   11 | 1611.44
 CLUELESS BUCKET             | Action      |      112.75 |   12 | 1724.19
 SOUTH WAIT                  | Action      |      107.78 |   13 | 1831.97
 DARN FORRESTER              | Action      |       93.82 |   14 | 1925.79
 CAMPUS REMEMBER             | Action      |       90.81 |   15 | 2016.60
 FORREST SONS                | Action      |       87.82 |   16 | 2104.42
 DEVIL DESIRE                | Action      |       83.85 |   17 | 2188.27
 DARKO DORADO                | Action      |       82.89 |   18 | 2271.16
 DREAM PICKUP                | Action      |       81.78 |   19 | 2352.94
 WEREWOLF LOLA               | Action      |       78.86 |   20 | 2431.80
...
 REAR TRADING                | Action      |       32.83 |   52 | 4163.15
 CELEBRITY HORN              | Action      |       32.76 |   53 | 4195.91
 DANCES NONE                 | Action      |       31.86 |   54 | 4227.77
 SIDE ARK                    | Action      |       29.88 |   55 | 4257.65
 DRAGON SQUAD                | Action      |       27.89 |   56 | 4285.54
 BULL SHAWSHANK              | Action      |       21.84 |   57 | 4307.38
 BRIDE INTRIGUE              | Action      |       21.81 |   58 | 4329.19
 CROW GREASE                 | Action      |       18.88 |   59 | 4348.07
 LAWRENCE LOVE               | Action      |       15.87 |   60 | 4363.94
 MONTEZUMA COMMAND           | Action      |       11.91 |   61 | 4375.85
 DOGMA FAMILY                | Animation   |      178.70 |    1 |  178.70
 SUNRISE LEAGUE              | Animation   |      170.76 |    2 |  349.46
 TITANIC BOONDOCK            | Animation   |      154.77 |    3 |  504.23
 FORRESTER COMANCHEROS       | Animation   |      146.73 |    4 |  650.96
 FALCON VOLUME               | Animation   |      127.77 |    5 |  778.73
 MISSION ZOOLANDER           | Animation   |      126.82 |    6 |  905.55
 DOORS PRESIDENT             | Animation   |      123.81 |    7 | 1029.36
 SLEEPLESS MONSOON           | Animation   |      121.80 |    8 | 1151.16
 THIEF PELICAN               | Animation   |      117.81 |    9 | 1268.97
 HORN WORKING                | Animation   |      112.76 |   10 | 1381.73
...

Note que o valor da soma (SUM) vai acumulando registro a registro até que uma nova categoria apareça. Isto é uma coisa muito difícil de se fazer com SQL puro, você não consegue fazer cálculos com base nos registros anteriores.

Agora nós podemos juntar esta última consulta com a primeira para calcular a porcentagem de vendas sobre o total da categoria. Vamos colocar cada uma das consultas como uma entrada em FROM:

SELECT
    sales.category,
    title,
    somatorio,
    total,
    (somatorio / total) * 100 AS porcentagem
    FROM
        (SELECT
            category,
            sum(total_sales) total
          FROM sales_pgday
          GROUP BY category) AS tot,
        (SELECT
            title,
            category,
            sum(total_sales) OVER (PARTITION BY category ORDER BY total_sales DESC) AS somatorio
          FROM sales_pgday) sales
    WHERE tot.category = sales.category;

O resultado será:

  category   |            title            | somatorio |  total  |       porcentagem
-------------+-----------------------------+-----------+---------+--------------------------
 Action      | FOOL MOCKINGBIRD            |    175.77 | 4375.85 |   4.01681958933692882500
 Action      | AMERICAN CIRCUS             |    343.55 | 4375.85 |   7.85104608247540477900
 Action      | STAGECOACH ARMAGEDDON       |    498.29 | 4375.85 |  11.38727332975307654500
 Action      | EASY GLADIATOR              |    649.06 | 4375.85 |  14.83277534650410777300
 Action      | MINDS TRUMAN                |    798.86 | 4375.85 |  18.25611024143880617500
 Action      | KISSING DOLLS               |    946.66 | 4375.85 |  21.63373973056663276800
 Action      | TRIP NEWTON                 |   1092.38 | 4375.85 |  24.96383559765531268200
 Action      | DRIFTER COMMANDMENTS        |   1234.14 | 4375.85 |  28.20343476124638641600
 Action      | SUSPECTS QUILLS             |   1367.84 | 4375.85 |  31.25884113943576676500
 Action      | WATERFRONT DELIVERANCE      |   1489.67 | 4375.85 |  34.04298593416136293500
 Action      | TRUMAN CRAZY                |   1611.44 | 4375.85 |  36.82575956671275295100
 Action      | CLUELESS BUCKET             |   1724.19 | 4375.85 |  39.40240181907515111300
 Action      | SOUTH WAIT                  |   1831.97 | 4375.85 |  41.86546613800747283400
 Action      | DARN FORRESTER              |   1925.79 | 4375.85 |  44.00950672440782933600
 Action      | CAMPUS REMEMBER             |   2016.60 | 4375.85 |  46.08476067506884376700
...
 Action      | REAR TRADING                |   4163.15 | 4375.85 |  95.13923009243918324400
 Action      | CELEBRITY HORN              |   4195.91 | 4375.85 |  95.88788463955574345600
 Action      | DANCES NONE                 |   4227.77 | 4375.85 |  96.61597175405921135300
 Action      | SIDE ARK                    |   4257.65 | 4375.85 |  97.29881051681387616100
 Action      | DRAGON SQUAD                |   4285.54 | 4375.85 |  97.93617240079070352000
 Action      | BULL SHAWSHANK              |   4307.38 | 4375.85 |  98.43527543220174366100
 Action      | BRIDE INTRIGUE              |   4329.19 | 4375.85 |  98.93369288252568072500
 Action      | CROW GREASE                 |   4348.07 | 4375.85 |  99.36515191334255059000
 Action      | LAWRENCE LOVE               |   4363.94 | 4375.85 |  99.72782430842007838500
 Action      | MONTEZUMA COMMAND           |   4375.85 | 4375.85 | 100.00000000000000000000
 Animation   | DOGMA FAMILY                |    178.70 | 4656.30 |   3.83781113759852243200
 Animation   | SUNRISE LEAGUE              |    349.46 | 4656.30 |   7.50510061636922019600
 Animation   | TITANIC BOONDOCK            |    504.23 | 4656.30 |  10.82898438674484032400
 Animation   | FORRESTER COMANCHEROS       |    650.96 | 4656.30 |  13.98019887034770096400
 Animation   | FALCON VOLUME               |    778.73 | 4656.30 |  16.72422309559091982900
 Animation   | MISSION ZOOLANDER           |    905.55 | 4656.30 |  19.44784485535725790900
 Animation   | DOORS PRESIDENT             |   1029.36 | 4656.30 |  22.10682301398105792200
 Animation   | SLEEPLESS MONSOON           |   1151.16 | 4656.30 |  24.72263385091166806300
...

O resultado é a porcentagem do total de vendas sendo acumulado até 100% e depois começando novamente para outra categoria. Com isso fica fácil atribuir A para os 20% mais significativos, B para os próximos 60% e C para os 20% menos significativos. Aqui, irei utilizar uma função CASE, que embora ocupe um bom espaço no nosso SQL é algo bastante trivial:

SELECT
    sales.category,
    title,
    TRUNC((somatorio / total) * 100) AS porcentagem,
    CASE
        WHEN (somatorio / total) <= 0.2 THEN 'A'
        WHEN (somatorio / total) > 0.2  AND  (somatorio / total) <= 0.8 THEN 'B'
        ELSE 'C' END AS curva_abc
    FROM
        (SELECT
            category,
            sum(total_sales) total
          FROM sales_pgday
          GROUP BY category) AS tot,
        (SELECT
            title,
            category,
            sum(total_sales) OVER (PARTITION BY category ORDER BY total_sales DESC) AS somatorio
          FROM sales_pgday) sales
    WHERE tot.category = sales.category;

E finalmente temos a nossa curva ABC:

  category   |            title            | porcentagem | curva_abc
-------------+-----------------------------+-------------+-----------
 Action      | FOOL MOCKINGBIRD            |           4 | A
 Action      | AMERICAN CIRCUS             |           7 | A
 Action      | STAGECOACH ARMAGEDDON       |          11 | A
 Action      | EASY GLADIATOR              |          14 | A
 Action      | MINDS TRUMAN                |          18 | A
 Action      | KISSING DOLLS               |          21 | B
 Action      | TRIP NEWTON                 |          24 | B
 Action      | DRIFTER COMMANDMENTS        |          28 | B
 Action      | SUSPECTS QUILLS             |          31 | B
 Action      | WATERFRONT DELIVERANCE      |          34 | B
 Action      | TRUMAN CRAZY                |          36 | B
...
 Action      | EXCITEMENT EVE              |          69 | B
 Action      | BAREFOOT MANCHURIAN         |          70 | B
 Action      | HANDICAP BOONDOCK           |          72 | B
 Action      | PARK CITIZEN                |          73 | B
 Action      | UPRISING UPTOWN             |          74 | B
 Action      | MOCKINGBIRD HOLLYWOOD       |          76 | B
 Action      | PATRIOT ROMAN               |          77 | B
 Action      | GRAIL FRANKENSTEIN          |          78 | B
 Action      | SHRUNK DIVINE               |          79 | B
 Action      | CADDYSHACK JEDI             |          81 | C
 Action      | GOSFORD DONNIE              |          82 | C
 Action      | ENTRAPMENT SATISFACTION     |          83 | C
 Action      | SPEAKEASY DATE              |          84 | C
 Action      | MIDNIGHT WESTWARD           |          85 | C
 Action      | FANTASY TROOPERS            |          86 | C
 Action      | WOMEN DORADO                |          87 | C
...
 Action      | DRAGON SQUAD                |          97 | C
 Action      | BULL SHAWSHANK              |          98 | C
 Action      | BRIDE INTRIGUE              |          98 | C
 Action      | CROW GREASE                 |          99 | C
 Action      | LAWRENCE LOVE               |          99 | C
 Action      | MONTEZUMA COMMAND           |         100 | C
 Animation   | DOGMA FAMILY                |           3 | A
 Animation   | SUNRISE LEAGUE              |           7 | A
 Animation   | TITANIC BOONDOCK            |          10 | A
 Animation   | FORRESTER COMANCHEROS       |          13 | A
 Animation   | FALCON VOLUME               |          16 | A
 Animation   | MISSION ZOOLANDER           |          19 | A
 Animation   | DOORS PRESIDENT             |          22 | B
 Animation   | SLEEPLESS MONSOON           |          24 | B
 Animation   | THIEF PELICAN               |          27 | B
 Animation   | HORN WORKING                |          29 | B
 Animation   | GANGS PRIDE                 |          32 | B
...

É claro que existem N coisas que você pode fazer com funções de janela. A documentação possui algumas explicações sobre este recurso e também uma lista com várias funções que você pode testar com a sua base, aproveitando como ponto de partida os exemplos mostrados aqui.

Boa diversão!



Sobre o PGCon Brasil, ou melhor PGBR

23 de Outubro de 2010, 0:00, por Software Livre Brasil - 0sem comentários ainda

A notícia agora é oficial, o PGBR 2010 foi cancelado.

Isso exige um pouco de reflexão. E como faz tempo que eu não faço isso por aqui, lá vai…

Bom, quem acompanha o blog aqui está careca de saber que em 2009 eu fui uma das pessoas que colaborou na organização da “III Conferência Brasileira de PostgreSQL“, também conhecida como PGCon Brasil 2009. Bom a organização de um evento deste porte não é nem de perto algo como a organização de um FISL. Mas não é nada simples. Quando você cobra R$ 100,00 pora alguém entrar num evento, tem que fazer este investimento voltar para a pessoa. É um compromisso que você assume. Não pode pisar na bola.

Para quem não sabe, existem 3 tipos de eventos que se encaixam aqui no Brasil:

  • O PG Metting, que seria algo como um Happy Hour com uma palestra e um convite para tomar uma cerveja depois. Em São Francisco, CA, o povo do PostgreSQL se encontra toda  na 3ª quinta-feira de cada mês. É algo que São Paulo, Brasília, Porto Alegre, Fortaleza, teriam todas as condições de fazer. Basta achar um local e criar a tradição. Tenho muita vontade de criar algo deste tipo aqui em São Paulo, mas não pode ser no dia do meu rodízio, hehehe.
  • O PGDay, que é um dia de palestras em um evento em geral direcionado para novatos. Assim como o PG Metting, pode ser organizado com custo zero, sem cobrar ingresso e sem patrocínio. Se tiver patrocínio, ótimo, mas não é preciso. Já foram vários PGDays com muito sucesso até agora. No ano passado tivemos: Brasília, São Paulo-SP, Porto Velho-RO, Ji-Paraná-RO, Porto Alegre-RS e ainda Florianópolis-SC. Este ano foram Ilheus-BA, Manaus-AM e São Paulo-SP, mas ainda deverá acontecer um no Rio de Janeiro-RJ. Vejam que não é pouca coisa. A simplicidade na organização e o aproveitamento de palestrantes locais é a chave do sucesso. E é a porta de entrada para novos colaboradores na comunidade.
  • O PGBR, antes era chamado de PGCon Brasil, mas atendendo ao pedido do Dan Languile, trocamos o nome. Questões internas, não vale a pena discutir e não é nenhum problema para nós. É o grande evento da comunidade nacional e tem tudo para ser referência em toda a América do Sul e é também um dos maiores eventos de usuários de PostgreSQL do mundo. Ele não é voltado para novatos, é voltado para quem já trabalha ou esta avaliando seriamente a possibilidade de trabalhar com o PostgreSQL. Aqui o nível das palestras vai de intermediário para avançado, passando por uma sala reservada aos Hackers onde o nível é para quem quer fazer coisas realmente divertidas.

<mimimi mode ON>
No ano passado a organização do PGCon Brasil 2009 tomou muito do meu tempo assim como o tempo de muitos outros como o Euler Taveira, Diogo Biazus, Leonardo Cezar, Fernando Ike, Marcelo Costa, a equipe da 4Linux e muitos outros mais. Mas houve algo curioso em 2009, que não houve nas outras 2 edições do evento em 2007 e 2008: pouca repercussão. Antes de depois do evento, vi pouca divulgação, comentários, posts em blogs, fotos, etc. E o mais estranho é que o evento deve defeitos mas não se pode dizer que foi pior que os anteriores, então o que aconteceu? Eu não sei exatamente o que aconteceu, só posso especular aqui. Uma pista é o que houve com muitos organizadores este ano: eu, Euler, Fike e Diogo, nos afastamos um pouco da comunidade. E isto teve um peso forte. Mas nós temos trabalhado juntos há alguns anos, o que houve? Bom, quando começamos, o PostgreSQL era quase um hobby para alguns de nós, hoje começa a ser meio de vida. Isso acontece em várias comunidades, eu vi isso claramente aqui no PSL-ABCD. Veja que por outro lado, este anos foram 3 palestrantes brasileiros no PGCon 2010, lá no Canadá! O nível tem crescido, e o nosso tempo disponível está indo para o ralo. De toda forma, depois de ralar muito, ver uma repercussão baixa após o PGCon 2009 também me desanimou um pouco.
<mimimi mode off>

O que aprendemos no passado

  • A burocracia é nosso inimigo número 1. Projeto de captação, contratos de patrocínio, notas fiscais, as inscrições, notas de empenho, prestação de contas, etc, etc, etc. Conseguir tirar esta parte burocrática da frente é uma meta que pode mudar tudo. A burocracia é o nosso maior inimigo. Ele nos leva ao próximo ponto:
  • As inscrições não podem ser realizadas pela comunidade. Receber dinheiro dá muito trabalho e fazer isso do jeito certo dá um absurdo de trabalho. Se tivéssemos patrocinadores em abundância, seria muito, mas muito mais fácil não cobrar nada. Não se trata apenas de ter um bom sistema para fazer as inscrições (coisa que o Euler fez do zero), não se trata apenas de ter banco, nota, recibo, documentação, etc. Se trata de ter alguém que atenda a meleca do telefone o tempo todo e resolva as dúvidas, encaminhe os processos bizarros de alguns órgãos públicos e suas notas de empenho from hell.
  • Patrocínio em troca de serviços é um bom negócio. Ao invés de receber dinheiro, receber o serviço. Foi assim com os brindes (canecas, pins, chaveiros, etc), com o credenciamento e com o Coffee Break. Tira uma boa parte da carga de burocracia e preocupação das nossas costas.
  • Começar a organização com pelo menos um ano antes e adiantar ao máximo as coisas no começo, garante que o evento saia, pois:
    • Reservar auditório com menos de 6 meses de antecedência é quase impossível, com 12 meses também não é tão fácil assim;
    • Ter o plano de captação pronto, com local e data definidos com mais de 6 meses de antecedência torna possível conseguir patrocínio. Com isso na mão, muitas portas vão bater na sua cara, mas outras vão se abrir. Sem isso, só na base da amizade mesmo, nem pense em órgãos públicos;
    • Os palestrantes internacionais precisam se agendar com muita antecedência e comprar passagens adiantado sai bem mais barato;
    • Com local, data e plano de captação prontos com um ano de antecedência, você tem tempo de se dedicar aos zilhões de detalhes que vão surgir nos 6 meses que antecedem o evento;
    • As inscrições tem de abrir cedo, para você começar a ter dinheiro em caixa cedo.
  • O valor das incrições tem de cobrir pelo menos os dois maiores custos do evento: a locação dos auditórios e o coffee-break.
  • Receber dinheiro de patrocinadores estrangeiros é um inferno. Então peça a eles que ajudem no pagamento de viagens de palestrantes internacionais;

Que venha o PGBR 2011!

Bom, e porquê o PGBR 2010 não deu certo? De certo não vale a pena entrar nesta questão. Pessoas, trabalharam muito para tentar organizar o evento mas isso não foi sificiente. A única coisa realmente óbivia é que a organização começou muito tarde. Mas de fato houveram pessoas que trabalharam bastante e imagino o quanto elas estejam frustradas agora. Muito mais do que aqueles que já aguardavam com expectativa o evento deste ano.

Agora é hora de pensar em 2011 e nos PGMettings e PGDays que podemos fazer em breve. Não temos tempo para ficar se remoendo mais, já estamos em cima da hora para começar o PGBR 2011. O mercado de PostgreSQL está crescendo, com o 9.0 está aparecendo um novo Standby em cada esquina. Vamos que vamos gente, que atrás vem muita gente!



O quanto você está ferrado com seu SGDB

26 de Agosto de 2010, 0:00, por Software Livre Brasil - 0sem comentários ainda

Sem comentários, entre no site e teste você mesmo:

http://howfuckedismydatabase.com/

Indicação do Marcelo Costa na lista do pgbr-geral.