Essa dúvida apareceu em outro lugar e estou postando aqui a solução.
O problema
Ao fazer um where coluna > 100000 o banco de dados estava retornando todos os valores. Mesmo alterando o tipo da coluna para numérico o resultado era sempre o mesmo.
A gambiarra
Alterar a função para where 1*coluna > 1*100000 para forçar o sistema a compreender o uso de valores numéricos.
Explicação e poréns
Isso funciona porque a maior parte das linguagens de programação trabalha da esquerda para direita, e portanto ao encontrar um “número” seguido de “uma operação numérica” ele vai forçar o outro lado da operação a ser numérico também.
Ao fazer “number * text” a linguagem vai tentar interpretar isso como “number * number”.
Primeiro porém, não vai funcionar sempre, não é elegante e não é eficiente. Isso deve ser usado como último recurso e não como estrategia.
Segundo porém, não funciona ao contrário, tem que colocar o “1” antes do elemento que está dando problemas.
Acho que é isso o resumo da gambiarra.
Qual sistema de banco de dados você está utilizando? A conversão implícita de tipos (implicit casting) que acontece no WHERE pode ser implementada de maneira diferente em sistemas de bancos de dados diferentes. Exemplo: crie uma tabela com uma coluna de texto, adicione textos que podem ser convertidos para inteiros e tente fazer a consulta WHERE coluna > N, onde N é inteiro (valor sem aspas).
Exemplo no SQLite
Converte implicitamente os valores da tabela para inteiro, dado que o valor na condição WHERE é inteiro:
sqlite> CREATE TABLE test (f1 TEXT);
sqlite> INSERT INTO test VALUES ('10'), ('20'), ('30');
sqlite> SELECT * FROM test WHERE f1 > 15;
20
30
Exemplo no PostgreSQL
O PostgreSQL se recusa a executar a consulta caso os tipos não sejam os mesmos:
rows=# CREATE TABLE test (f1 TEXT);
CREATE TABLE
rows=# INSERT INTO test VALUES ('10'), ('20'), ('30');
INSERT 0 3
rows=# SELECT * FROM test WHERE f1 > 15;
ERROR: operator does not exist: text > integer
LINE 1: SELECT * FROM test WHERE f1 > 15;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
É uma boa prática fazer a conversão explícita, pois dessa forma os erros não passam despercebidos (sugiro ver a palestra WAT do Gary Bernhardt para ver os efeitos bizarros disso). O casting explícito pode ser feito de duas formas, como no exemplo abaixo (o nome do banco de dados é rows):
rows=# SELECT * FROM test WHERE f1::INTEGER > 15;
f1
----
20
30
(2 rows)
rows=# SELECT * FROM test WHERE CAST(f1 AS INTEGER) > 15;
f1
----
20
30
(2 rows)
Você também poderia converter o valor da coluna para inteiro e então não precisaria do casting explícito:
rows=# ALTER TABLE test ALTER COLUMN f1 TYPE INTEGER USING f1::INTEGER;
ALTER TABLE
rows=# SELECT * FROM test WHERE f1 > 15;
f1
----
20
30
(2 rows)
1 curtida