Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-08 8:28 GMT-02:00 Matheus de Oliveira matioli.math...@gmail.com: Nossa cara, desculpe, mas por favor não faça isso. Criar uma sequence (mesmo temporária) para ter algo que uma simples WINDOW FUNCTION row_number (o mesmo do seu alias) já faz, me parece péssimo, além disso para array o generate_subscripts já resolve, você viu a solução que eu propus? Vi agora. =\ Todo caso a idéia de propor a solução ruim era forçar alguma alma caridosa a pensar em algo melhor. :P De qualquer forma a ideia de um JOIN com o resultado do unnest pode não ser ruim, mas seria interessante testar bem a diferença de performance desse método, sei que para grandes listas isso pode ser melhor que usar IN, mas é difícil determinar o que é grande. Tu tem alguma sugestão quantos registros seriam o ideal pra medir esses tempos? To curioso pra saber qual deles se comporta melhor. -- Sebastian Webber http://swebber.me ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-08 10:16 GMT-02:00 Sebastian Webber sebastian...@gmail.com: 2015-01-08 8:28 GMT-02:00 Matheus de Oliveira matioli.math...@gmail.com: Nossa cara, desculpe, mas por favor não faça isso. Criar uma sequence (mesmo temporária) para ter algo que uma simples WINDOW FUNCTION row_number (o mesmo do seu alias) já faz, me parece péssimo, além disso para array o generate_subscripts já resolve, você viu a solução que eu propus? Vi agora. =\ Todo caso a idéia de propor a solução ruim era forçar alguma alma caridosa a pensar em algo melhor. :P Eu já pensei em algo, dá uma olhada: CREATE OR REPLACE FUNCTION fordena_sql(int[]) RETURNS TABLE (item int, ordem int) AS $$ SELECT unnest($1) as item, generate_series(1,array_length($1,1)) as ordem ; $$ LANGUAGE 'sql'; SELECT foo.id, foo.name, fordena_sql.ordem FROM foo, fordena_sql(ARRAY[1,5,20,12]) WHERE foo.id = fordena_sql.item ORDER BY fordena_sql.ordem; e o resultado: postgres=# SELECT foo.id, foo.name, fordena_sql.ordem FROM foo, fordena_sql(ARRAY[1,5,20,12]) postgres-# WHERE foo.id = fordena_sql.item ORDER BY fordena_sql.ordem;WHERE foo.id = fordena_sql.item postgres-# ORDER BY fordena_sql.ordem;ORDER BY fordena_sql.ordem; id | name | ordem +-+--- 1 | name 1 | 1 5 | name 5 | 2 20 | name 20 | 3 12 | name 12 | 4 (4 rows) a parte legal é agora nem precisa de pl/pgsql! :D -- Sebastian Webber http://swebber.me ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-07 16:32 GMT-02:00 Sebastian Webber sebastian...@gmail.com: -- workaround starts DROP SEQUENCE IF EXISTS temp_seq; CREATE TEMP sequence temp_seq; -- workaround ends WITH items_parafiltrar as ( SELECT UNNEST(ARRAY[1,5,20,12]) AS filtro ), lista as ( SELECT nextval('temp_seq') As row_number, items_parafiltrar.filtro as item FROM items_parafiltrar ) SELECT foo.id, foo.name , lista.row_number FROM foo, lista where foo.id = lista.item order by lista.row_number; Nossa cara, desculpe, mas por favor não faça isso. Criar uma sequence (mesmo temporária) para ter algo que uma simples WINDOW FUNCTION row_number (o mesmo do seu alias) já faz, me parece péssimo, além disso para array o generate_subscripts já resolve, você viu a solução que eu propus? De qualquer forma a ideia de um JOIN com o resultado do unnest pode não ser ruim, mas seria interessante testar bem a diferença de performance desse método, sei que para grandes listas isso pode ser melhor que usar IN, mas é difícil determinar o que é grande. Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Valeu pessoal! Utlizei a função e fechou! CREATE OR REPLACE FUNCTION fordenacao( vfield text, vin text) RETURNS text AS $BODY$ DECLARE vorder integer DEFAULT 1; vindice integer; vcodigo integer[] DEFAULT string_to_array(vin,',')::integer[]; vordenacao text DEFAULT ''; BEGIN FOR vindice IN array_lower(vcodigo,1)..array_upper(vcodigo,1) LOOP vordenacao := vordenacao||' WHEN '||vcodigo[vindice]::text||' THEN '||vorder::text; vorder := vorder + 1; END LOOP; vordenacao := '(CASE '||vfield||' '||vordenacao||' END)'; RETURN vordenacao; END; $BODY$ LANGUAGE Muito obrigado pessoal! Em 08/01/2015, à(s) 08:28, Matheus de Oliveira matioli.math...@gmail.com escreveu: 2015-01-07 16:32 GMT-02:00 Sebastian Webber sebastian...@gmail.com mailto:sebastian...@gmail.com: -- workaround starts DROP SEQUENCE IF EXISTS temp_seq; CREATE TEMP sequence temp_seq; -- workaround ends WITH items_parafiltrar as ( SELECT UNNEST(ARRAY[1,5,20,12]) AS filtro ), lista as ( SELECT nextval('temp_seq') As row_number, items_parafiltrar.filtro as item FROM items_parafiltrar ) SELECT foo.id http://foo.id/, foo.name http://foo.name/ , lista.row_number FROM foo, lista where foo.id http://foo.id/ = lista.item order by lista.row_number; Nossa cara, desculpe, mas por favor não faça isso. Criar uma sequence (mesmo temporária) para ter algo que uma simples WINDOW FUNCTION row_number (o mesmo do seu alias) já faz, me parece péssimo, além disso para array o generate_subscripts já resolve, você viu a solução que eu propus? De qualquer forma a ideia de um JOIN com o resultado do unnest pode não ser ruim, mas seria interessante testar bem a diferença de performance desse método, sei que para grandes listas isso pode ser melhor que usar IN, mas é difícil determinar o que é grande. Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres http://www.dextra.com.br/postgres/ ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-08 8:32 GMT-02:00 Marcelo Florindo marceloflori...@gmail.com: CREATE OR REPLACE FUNCTION fordenacao( vfield text, vin text) RETURNS text AS $BODY$ DECLARE vorder integer DEFAULT 1; vindice integer; vcodigo integer[] DEFAULT string_to_array(vin,',')::integer[]; vordenacao text DEFAULT ''; BEGIN FOR vindice IN array_lower(vcodigo,1)..array_upper(vcodigo,1) LOOP vordenacao := vordenacao||' WHEN '||vcodigo[vindice]::text||' THEN '||vorder::text; vorder := vorder + 1; END LOOP; vordenacao := '(CASE '||vfield||' '||vordenacao||' END)'; RETURN vordenacao; END; $BODY$ LANGUAGE Muito obrigado pessoal! Marcelo, Como eu já comentei em [1], essa função está incorreta. Ou estou enganado e alguém quer me ajudar a entender como isso seria uma solução correta? [1] http://www.mail-archive.com/pgbr-geral@listas.postgresql.org.br/msg39367.html Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Matheus, Para mim funcionou pois eu retorno uma string e depois que irei executar. Grato, Marcelo Em 08/01/2015, à(s) 13:12, Matheus de Oliveira matioli.math...@gmail.com escreveu: 2015-01-08 8:32 GMT-02:00 Marcelo Florindo marceloflori...@gmail.com mailto:marceloflori...@gmail.com: CREATE OR REPLACE FUNCTION fordenacao( vfield text, vin text) RETURNS text AS $BODY$ DECLARE vorder integer DEFAULT 1; vindice integer; vcodigo integer[] DEFAULT string_to_array(vin,',')::integer[]; vordenacao text DEFAULT ''; BEGIN FOR vindice IN array_lower(vcodigo,1)..array_upper(vcodigo,1) LOOP vordenacao := vordenacao||' WHEN '||vcodigo[vindice]::text||' THEN '||vorder::text; vorder := vorder + 1; END LOOP; vordenacao := '(CASE '||vfield||' '||vordenacao||' END)'; RETURN vordenacao; END; $BODY$ LANGUAGE Muito obrigado pessoal! Marcelo, Como eu já comentei em [1], essa função está incorreta. Ou estou enganado e alguém quer me ajudar a entender como isso seria uma solução correta? [1] http://www.mail-archive.com/pgbr-geral@listas.postgresql.org.br/msg39367.html http://www.mail-archive.com/pgbr-geral@listas.postgresql.org.br/msg39367.html Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres http://www.dextra.com.br/postgres/ ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-08 13:35 GMT-02:00 Marcelo Florindo marceloflori...@gmail.com: Para mim funcionou pois eu retorno uma string e depois que irei executar. Credo... Eu ainda acho que as funções como o Sebastian e eu criamos sejam opções melhores, mas... At. -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-07 4:59 GMT-02:00 Danilo Silva danilo.dsg.go...@gmail.com: CREATE OR REPLACE FUNCTION fordenacao(vfield text,vin text) RETURNS text AS $$ DECLARE vorder integer DEFAULT 1; vindice integer; vcodigo integer[] DEFAULT string_to_array(vin,',')::integer[]; vordenacao text DEFAULT ''; BEGIN FOR vindice IN array_lower(vcodigo,1)..array_upper(vcodigo,1) LOOP vordenacao := vordenacao||' WHEN '||vcodigo[vindice]::text||' THEN '||vorder::text; vorder := vorder + 1; END LOOP; vordenacao := '(CASE '||vfield||' '||vordenacao||' END)'; RETURN vordenacao; END; $$ LANGUAGE plpgsql; Select * from fabricante where id in (10,14,29,49,20) ORDER BY fordenacao('id','10,14,29,49,20') Isso não vai funcionar. Sua função retorna um texto com o CASE, isso não significa que o PostgreSQL irá executar o comando deste texto, apenas irá ordernar pelo texto em si, e com certeza não é o que o querias. Se quiser fazer a coisa realmente dinâmica, você pode sim usar uma função. Eu trocaria a lista do IN por array, assim pode-se usar a seguinte lógica (não testada): SELECT * FROM fabricante f WHERE f.id =ANY($1) ORDER BY (SELECT i FROM generate_subscripts($1, 1) i WHERE $1[i] = f.id) Onde $1 é o parâmetro '{10,14,29,49,20}'::int[]. Claro, que você pode simplicar as coisas e colocar a sub-consulta numa função (também não testada): CREATE OR REPLACE FUNCTION array_index_of(anyarray, anyvalue) RETURNS int LANGUAGE SQL AS $$ SELECT i FROM generate_subscripts($1, 1) i WHERE $1[i] = $2 $$; Daí é só modificar a consulta para: SELECT * FROM fabricante f WHERE f.id =ANY($1) ORDER BY array_index_of($1, f.id); OBS1: Ambos casos teriam problema caso o array não tenha elementos únicos, nesse caso adicione um LIMIT 1 para pegar o primeiro que casar. OBS2: Em termos de performance não tem muito o que fazer, o Sort sempre aparecerá, não é possível indexar nesse caso, a não ser que faça indexação para arrays específicos. Entretanto um índice em id já ajuda no filtro =ANY/IN. Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! Marcelo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral order by id? ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-07 10:57 GMT-02:00 Carlos Antônio Pereira (VidaUTI) carlosanto...@utivida.com.br: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! order by id? Isso já foi sugerido. E não funciona, pois ordenaria pelo id e não pelos elementos informados para o IN. No exemplo em questão, o valor 20 foje da ordem do id. Atenciosamente, -- Matheus de Oliveira Analista de Banco de Dados Dextra Sistemas - MPS.Br nível F! www.dextra.com.br/postgres ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
2015-01-07 14:36 GMT-02:00 Matheus de Oliveira matioli.math...@gmail.com: Isso já foi sugerido. E não funciona, pois ordenaria pelo id e não pelos elementos informados para o IN. No exemplo em questão, o valor 20 foje da ordem do id. Eu só consegui pensar numa *gambiarra* pra fazer funcionar dessa forma (com a ordem dos filtros): postgres=# create table foo( id serial primary key, name text); CREATE TABLE postgres=# insert into foo (name) select 'name ' || generate_series(1,100) as name ; INSERT 0 100 -- workaround starts DROP SEQUENCE IF EXISTS temp_seq; CREATE TEMP sequence temp_seq; -- workaround ends WITH items_parafiltrar as ( SELECT UNNEST(ARRAY[1,5,20,12]) AS filtro ), lista as ( SELECT nextval('temp_seq') As row_number, items_parafiltrar.filtro as item FROM items_parafiltrar ) SELECT foo.id, foo.name , lista.row_number FROM foo, lista where foo.id = lista.item order by lista.row_number; e a saida: postgres-# order by lista.row_number;order by lista.row_number; id | name | row_number +-+ 1 | name 1 | 1 5 | name 5 | 2 20 | name 20 | 3 12 | name 12 | 4 (4 rows) Agora, minhas considerações: 1) pra que, OBRIGATORIAMENTE, tem que ser nessa ordem? 2) seria mais elegante fazer sem a sequence, mas a função de row_number (das window functions) precisa de um ordem by e aí já bagunça nossa ordem duvidosa. 3) não precisa ser um array com o filtro, mas convenhamos, é mais fácil digitar no array do que ficar fazendo union dos registros. :P Peguei a idéia desse link[1] pra fazer o row num sem o ordem by. Certamente dá pra usar outra solução ou pensar em algo mais elegante. [1] http://www.postgresonline.com/journal/archives/79-Simulating-Row-Number-in-PostgreSQL-Pre-8.4.html -- Sebastian Webber http://swebber.me ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
order by (case when 10 then 1 when 14 then 2 when 29 then 3 when 49 then 4 when 20 then 5 end) Em 6 de janeiro de 2015 19:19, Marcelo Florindo marceloflori...@gmail.com escreveu: Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! Marcelo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- Marcos Thomaz da Silva Analista de Tecnologia da Informação ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
[pgbr-geral] Ordenando conforme itens na clausula in
Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! Marcelo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Marcos, No meu caso os valores são dinâmicos. Existe alguma forma de automatizar isto? Obrigado! Marcelo Em 06/01/2015, à(s) 22:24, Marcos Thomaz marcosthom...@gmail.com escreveu: order by (case when 10 then 1 when 14 then 2 when 29 then 3 when 49 then 4 when 20 then 5 end) Em 6 de janeiro de 2015 19:19, Marcelo Florindo marceloflori...@gmail.com mailto:marceloflori...@gmail.com escreveu: Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! Marcelo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br mailto:pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- Marcos Thomaz da Silva Analista de Tecnologia da Informação ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Em 6 de janeiro de 2015 22:19, Marcelo Florindo marceloflori...@gmail.com escreveu: Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Crie uma função que faça a ordenação: CREATE OR REPLACE FUNCTION fordenacao(vfield text,vin text) RETURNS text AS $$ DECLARE vorder integer DEFAULT 1; vindice integer; vcodigo integer[] DEFAULT string_to_array(vin,',')::integer[]; vordenacao text DEFAULT ''; BEGIN FOR vindice IN array_lower(vcodigo,1)..array_upper(vcodigo,1) LOOP vordenacao := vordenacao||' WHEN '||vcodigo[vindice]::text||' THEN '||vorder::text; vorder := vorder + 1; END LOOP; vordenacao := '(CASE '||vfield||' '||vordenacao||' END)'; RETURN vordenacao; END; $$ LANGUAGE plpgsql; Select * from fabricante where id in (10,14,29,49,20) ORDER BY fordenacao('id','10,14,29,49,20') Não sei dizer se é a melhor solução...mas vale a ajuda. Não esqueça de analisar a performance... []s Danilo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral
Re: [pgbr-geral] Ordenando conforme itens na clausula in
Se a construção do SQL (da cláusula IN) vier da aplicação, o ideal seria automatizar pela aplicação a criação da parte referente a ordenação também. Pode ser que exista uma forma mais simples, mas pelo menos no momento não consigo me lembrar. Em 6 de janeiro de 2015 21:53, Marcelo Florindo marceloflori...@gmail.com escreveu: Marcos, No meu caso os valores são dinâmicos. Existe alguma forma de automatizar isto? Obrigado! Marcelo Em 06/01/2015, à(s) 22:24, Marcos Thomaz marcosthom...@gmail.com escreveu: order by (case when 10 then 1 when 14 then 2 when 29 then 3 when 49 then 4 when 20 then 5 end) Em 6 de janeiro de 2015 19:19, Marcelo Florindo marceloflori...@gmail.com escreveu: Boa noite colegas, Eu tenho este sql: Select * from fabricante where id in (10,14,29,49,20) Preciso que o select venha na mesma ordem do in, alguma ideia? Grato a todos e feliz 2015!!! Marcelo ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- Marcos Thomaz da Silva Analista de Tecnologia da Informação ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral -- Marcos Thomaz da Silva Analista de Tecnologia da Informação ___ pgbr-geral mailing list pgbr-geral@listas.postgresql.org.br https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral