SQL - Retornar a linha com o menor valor de uma coluna, entre várias colunas com valores diferentes.

25/10/2021

0

Olá,

Preciso de ajuda para elaborar uma query em um banco de dados SQL, onde a mesma me retorne o produto que tem o menor valor entre todos, sendo que cada produto possui 5 valores distintos ou iguais, sendo que a query não pode trazer valores null, ou zero.
Exemplo:

Tenho os seguintes produtos e valores:

PRODUTO A -> ID = '' 1 '' VALORES => 4, 2, 9 , 0 ,7
PRODUTO B -> ID = '' 2 '' VALORES => 0, 0, 3, 1, 7
PRODUTO C-> ID = '' 3 '' VALORES => 9, 0, 4 , 5, 2

No caso gostaria que a query me retornasse a linha com ID = '' 2 ''
pois ignoraria os zeros e nulls, e o menor preço entre todas as linha seria o 1.

Alguém pode me ajudar ? Desde já agradeço a ajuda !!!
Bruno Murad

Bruno Murad

Responder

Posts

27/10/2021

Emerson Nascimento

VALORES é uma coluna ou são várias colunas?
Quanto mais informações puder passar, mais fácil ter uma resposta pertinente.
Lembre-se: não conhecemos a estrutura das tuas tabelas; não temos acesso ao teu banco de dados.
Responder

27/10/2021

Bruno Murad

VALORES é uma coluna ou são várias colunas?
Quanto mais informações puder passar, mais fácil ter uma resposta pertinente.
Lembre-se: não conhecemos a estrutura das tuas tabelas; não temos acesso ao teu banco de dados.


valores, são várias colunas cada uma com um valor dessa forma:

+----------+----------+----------+----------+---------+---------+---------+
| id | Prod | Val1 | Val2 | Val3 | Val4 | Val5 |
+----------+----------+-----------+----------+--------+---------+---------+
| 1 | A | 4 | 2 | 9 | 0 | 7 |
+----------+----------+-----------+----------+--------+---------+---------+
| 2 | B | 0 | 0 | 3 | 1 | 7 |
+----------+----------+-----------+----------+--------+---------+---------+
| 3 | C | 9 | 0 | 4 | 5 | 2 |
+----------+----------+-----------+----------+--------+---------+---------+

Preciso de uma query que me retorne o ID 2, pois ele tem o menor valor entre todos os produtos, descartando os campos com valor zero.
Acho que assim ficou melhor de entender...


Responder

27/10/2021

Emerson Nascimento


qual o banco de dados utilizado ?
sql server
firebird
mysql
postgre
oracle
Responder

27/10/2021

Bruno Murad


qual o banco de dados utilizado ?
sql server
firebird
mysql
postgre
oracle


Desculpe a falta de atenção... estou trabalhando com mysql e php.
Responder

28/10/2021

Emerson Nascimento

segundo minhas pesquisas o MySQL não tem função própria pra isso, então tem que ser na 'criatividade'.
+----+------+------+------+------+------+------+
| id | Prod | Val1 | Val2 | Val3 | Val4 | Val5 |
+----+------+------+------+------+------+------+
| 1  | A    | 4    | 2    | 9    | 0    | 7    |
+----+------+------+------+------+------+------+
| 2  | B    | 0    | 0    | 3    | 1    | 7    |
+----+------+------+------+------+------+------+
| 3  | C    | 9    | 0    | 4    | 5    | 2    |
+----+------+------+------+------+------+------+
com base na tabela acima, a primeira coisa a fazer é transformar as colunas em linhas.
a instrução abaixo não é a melhor (se você acrescentar a coluna Val6 terá que fazer manutenção no código) mas acredito que seja a única possível até o momento.
SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
o resultado será:
+----+------+-------+----------+
| id | Prod | CAMPO | CONTEUDO |
+----+------+-------+----------+
| 1  | A    | Val1  | 4        |
+----+------+-------+----------+
| 1  | A    | Val2  | 2        |
+----+------+-------+----------+
| 1  | A    | Val3  | 9        |
+----+------+-------+----------+
| 1  | A    | Val5  | 7        |
+----+------+-------+----------+
| 2  | B    | Val3  | 3        |
+----+------+-------+----------+
| 2  | B    | Val4  | 1        |
+----+------+-------+----------+
| 2  | B    | Val5  | 7        |
+----+------+-------+----------+
| 3  | C    | Val1  | 9        |
+----+------+-------+----------+
| 3  | C    | Val3  | 4        |
+----+------+-------+----------+
| 3  | C    | Val4  | 5        |
+----+------+-------+----------+
| 3  | C    | Val5  | 2        |
+----+------+-------+----------+
sabendo que os dados estão corretos, basta usar a mesma consulta executada anteriormente, porém agora agrupada:
SELECT id, prod, min(CONTEUDO) VALOR FROM
(
	SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
	SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
	SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
	SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
	SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
) TAB
GROUP BY id, prod
o resultado será:
+----+------+-------+-------+
| id | Prod | CAMPO | VALOR |
+----+------+-------+-------+
| 1  | A    | Val2  | 2     |
+----+------+-------+-------+
| 2  | B    | Val4  | 1     |
+----+------+-------+-------+
| 3  | C    | Val5  | 2     |
+----+------+-------+-------+
com esse resultado em mãos, podemos obter o id do menor valor utilizando a cláusula LIMIT e a cláusula ORDER BY:
SELECT id, prod, min(CONTEUDO) VALOR FROM
(
	SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
	SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
	SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
	SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
	SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
) TAB
GROUP BY id, prod
ORDER BY VALOR -- não sei se o MySQL trabalha com o alias do campo. Se não funcionar tente com o índice do campo (3) ou com a função de agregação (min(CONTEUDO))
LIMIT 1
o resultado será:
+----+------+-------+
| id | Prod | VALOR |
+----+------+-------+
| 2  | B    | 1     |
+----+------+-------+



Responder

28/10/2021

Bruno Murad

segundo minhas pesquisas o MySQL não tem função própria pra isso, então tem que ser na 'criatividade'.
+----+------+------+------+------+------+------+
| id | Prod | Val1 | Val2 | Val3 | Val4 | Val5 |
+----+------+------+------+------+------+------+
| 1  | A    | 4    | 2    | 9    | 0    | 7    |
+----+------+------+------+------+------+------+
| 2  | B    | 0    | 0    | 3    | 1    | 7    |
+----+------+------+------+------+------+------+
| 3  | C    | 9    | 0    | 4    | 5    | 2    |
+----+------+------+------+------+------+------+
com base na tabela acima, a primeira coisa a fazer é transformar as colunas em linhas.
a instrução abaixo não é a melhor (se você acrescentar a coluna Val6 terá que fazer manutenção no código) mas acredito que seja a única possível até o momento.
SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
o resultado será:
+----+------+-------+----------+
| id | Prod | CAMPO | CONTEUDO |
+----+------+-------+----------+
| 1  | A    | Val1  | 4        |
+----+------+-------+----------+
| 1  | A    | Val2  | 2        |
+----+------+-------+----------+
| 1  | A    | Val3  | 9        |
+----+------+-------+----------+
| 1  | A    | Val5  | 7        |
+----+------+-------+----------+
| 2  | B    | Val3  | 3        |
+----+------+-------+----------+
| 2  | B    | Val4  | 1        |
+----+------+-------+----------+
| 2  | B    | Val5  | 7        |
+----+------+-------+----------+
| 3  | C    | Val1  | 9        |
+----+------+-------+----------+
| 3  | C    | Val3  | 4        |
+----+------+-------+----------+
| 3  | C    | Val4  | 5        |
+----+------+-------+----------+
| 3  | C    | Val5  | 2        |
+----+------+-------+----------+
sabendo que os dados estão corretos, basta usar a mesma consulta executada anteriormente, porém agora agrupada:
SELECT id, prod, min(CONTEUDO) VALOR FROM
(
	SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
	SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
	SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
	SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
	SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
) TAB
GROUP BY id, prod
o resultado será:
+----+------+-------+-------+
| id | Prod | CAMPO | VALOR |
+----+------+-------+-------+
| 1  | A    | Val2  | 2     |
+----+------+-------+-------+
| 2  | B    | Val4  | 1     |
+----+------+-------+-------+
| 3  | C    | Val5  | 2     |
+----+------+-------+-------+
com esse resultado em mãos, podemos obter o id do menor valor utilizando a cláusula LIMIT e a cláusula ORDER BY:
SELECT id, prod, min(CONTEUDO) VALOR FROM
(
	SELECT id , prod, 'Val1' CAMPO, Val1 CONTEUDO FROM tabela WHERE coalesce(Val1,0) > 0 UNION ALL
	SELECT id , prod, 'Val2' CAMPO, Val2 CONTEUDO FROM tabela WHERE coalesce(Val2,0) > 0 UNION ALL
	SELECT id , prod, 'Val3' CAMPO, Val3 CONTEUDO FROM tabela WHERE coalesce(Val3,0) > 0 UNION ALL
	SELECT id , prod, 'Val4' CAMPO, Val4 CONTEUDO FROM tabela WHERE coalesce(Val4,0) > 0 UNION ALL
	SELECT id , prod, 'Val5' CAMPO, Val5 CONTEUDO FROM tabela WHERE coalesce(Val5,0) > 0
) TAB
GROUP BY id, prod
ORDER BY VALOR -- não sei se o MySQL trabalha com o alias do campo. Se não funcionar tente com o índice do campo (3) ou com a função de agregação (min(CONTEUDO))
LIMIT 1
o resultado será:
+----+------+-------+
| id | Prod | VALOR |
+----+------+-------+
| 2  | B    | 1     |
+----+------+-------+





Perfeito !!! Funcionou corretamente !!!
Obrigado pela ajuda e pela excelente explicação passo a passo do processo. Com ele consegui resolver a situação e de quebra ainda adquiri esse excelente conhecimento que me passou, mais uma vez muito obrigado pela aula !!!
Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar