Exibir os 3 menores valores inclusive repetidos

Galera,

Estou usando MySql e fiz um select que me retorna os 3 menores valores de uma tabela como o exemplo abaixo:

Se eu tiver algum valor repetido ele não me apresenta a repetição.

Se os preços das Tvs fossem 100,200,200,300,400 o select me retornaria 100,200,300 eliminando a repetição, mas o resultado que eu gostaria de obter é: 100,200,200,300;

Alguem sabe como posso fazer isso?

Bom dia Amigo,

Nesse caso quando você diz:

[quote=socialclub]
mas o resultado que eu gostaria de obter é: 100,200,200,300;

Alguem sabe como posso fazer isso?[/quote]

Você quer pegar apenas os 3 primeiros(100, 200, 200)?

Nesse caso não sua query já terá esse comportamento, agora se o que você quer é pegar os 3 menos valores distintos, você pode fazer:

select DISTINCT(menorPreco), <outras colunas que queira trazer> from protudo where item='tv' order by menorPreco asc limit 3";

Olá Guilherme,

Obrigado pela resposta.

Eu quero pegar os 3 menores valores, caso um deles possua repetição também quero pegar a repetição entende?

Exemplo: os valores são 100, 200, 200, 300, 400.

Dai ele pegaria o primeiro valor que é 100, pegaria o segundo que é 200 e também a sua repetição 200 e o terceiro que é 300.

[quote=socialclub]Olá Guilherme,

Obrigado pela resposta.

Eu quero pegar os 3 menores valores, caso um deles possua repetição também quero pegar a repetição entende?

Exemplo: os valores são 100, 200, 200, 300, 400.

Dai ele pegaria o primeiro valor que é 100, pegaria o segundo que é 200 e também a sua repetição 200 e o terceiro que é 300.[/quote]

Neste caso citado o limite seria 4. Caso houvessem mais repetições o limite aumentaria proporcionalmente.
Talvez fosse melhor definir um limite máximo não importando as repetições e tratar isso a nível de aplicação.

Por exemplo, no banco buscar sempre os 10 menores e na aplicação realizar as verificações para retornar somente 3 e as repetições. Se bem que, e se você tiver por exemplo 100 registros e todos iguais, qual deveria ser o comportamento? É preciso entender melhor essa regra de negócio.

O teu select está, aparentemente, correto.
A questão é se a cláusula WHERE está sendo atendida a contento.

mysql> create table produto(
    -> id bigint not null auto_increment,
    -> nome varchar(200) not null,
    -> preco float(13,2) not null,
    -> primary key(id));
Query OK, 0 rows affected (0.45 sec)

mysql> insert into produto(nome, preco) values ('prd1', 200);
Query OK, 1 row affected (0.04 sec)

mysql> insert into produto(nome, preco) values ('prd2', 200);
Query OK, 1 row affected (0.02 sec)

mysql> insert into produto(nome, preco) values ('prd3', 230);
Query OK, 1 row affected (0.04 sec)

mysql> insert into produto(nome, preco) values ('prd4', 240);
Query OK, 1 row affected (0.02 sec)

mysql> insert into produto(nome, preco) values ('prd5', 210);
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM produto ORDER BY preco ASC LIMIT 3;
+----+------+--------+
| id | nome | preco  |
+----+------+--------+
|  1 | prd1 | 200.00 |
|  2 | prd2 | 200.00 |
|  5 | prd5 | 210.00 |
+----+------+--------+
3 rows in set (0.02 sec)

drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o

[quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]

Isso Frederico. Exatamente isso que estou tentando fazer! :slight_smile:

[quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]
Ele quer os três menores, isso significa que se ele tiver 5 registros com o preço R$ 0,01 (o menor preço possível a um produto), ele trará apenas 3, independente destes.

A pergunta dele é quanto à forma como o SELECT está trazendo os resultados, ao invés de 200, 200 e 300, ele traz 200, 300 e 400, ignorando uma das repetições.

[quote=socialclub][quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]

Isso Frederico. Exatamente isso que estou tentando fazer! :)[/quote]
Se é isso, o limit 3 nunca vai contemplar mais que 3.
A melhor solução é fazer o select sem limit (ou um limit para paginação) e tratar na aplicação.

O que ele quer é algo assim:

    select p.* from produto p where p.item='tv' and p.menorPreco IN (SELECT distinct p2.menorPreco FROM produto p2 where p2.item='tv' order by p2.menorPreco asc limit 3) order by p.menorPreco asc 

Nota: Não sei se no mysql dá para fazer o inner select assim.

[quote=drsmachado][quote=socialclub][quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]

Isso Frederico. Exatamente isso que estou tentando fazer! :)[/quote]
Se é isso, o limit 3 nunca vai contemplar mais que 3.
A melhor solução é fazer o select sem limit (ou um limit para paginação) e tratar na aplicação.[/quote]

Foi o que eu sugeri. É o que acho também.

[quote=fredericomaia10][quote=drsmachado][quote=socialclub][quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]

Isso Frederico. Exatamente isso que estou tentando fazer! :)[/quote]
Se é isso, o limit 3 nunca vai contemplar mais que 3.
A melhor solução é fazer o select sem limit (ou um limit para paginação) e tratar na aplicação.[/quote]

Foi o que eu sugeri. É o que acho também. [/quote]

Se eu fizer o select sem limit ele vai me retornar todos os valores da tabela, não seria isso?

Sim. Pode trazer apenas ordenado pelo menor. E na aplicação, no Java, você faz a lógica que quer.

[quote=socialclub][quote=fredericomaia10][quote=drsmachado][quote=socialclub][quote=fredericomaia10]drsmachado pelo que entendi do que ele pediu, neste exemplo que você deu o retorno que ele queria era 200, 200 (mesmo que repetido), 230, 240.
Ou seja os 3 menores, porém se houver algum repetido tem que traze-lo também. Retornando no exemplo acima, 4 registros e não 3.
O.o[/quote]

Isso Frederico. Exatamente isso que estou tentando fazer! :)[/quote]
Se é isso, o limit 3 nunca vai contemplar mais que 3.
A melhor solução é fazer o select sem limit (ou um limit para paginação) e tratar na aplicação.[/quote]

Foi o que eu sugeri. É o que acho também. [/quote]

Se eu fizer o select sem limit ele vai me retornar todos os valores da tabela, não seria isso?[/quote]
Todos os que coincidirem com a cláusula where

Ah, e quanto a sugestão do PMLM:

mysql> select * FROM produto
    -> where valor IN (select distinct(valor) from produto order by valor asc limit 3);
ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'

Então, apenas uma SP poderia resolver, direto no banco.
Na aplicação, ele pode realizar uma consulta, obter os 3 menores preços e então fazer uma nova busca…