SQL get field from row with max / min field

107 views Asked by At

So there is school project and I completely stuck on last step. There's my code:

SELECT Consumidor.numero, Soma.soma
FROM Consumidor
JOIN
  (SELECT compra.consumidor, SUM(Eco.eco*compra.quantidade) as soma
   FROM compra
   JOIN
    (SELECT composto.produto, composto.prodMarca, Produto.nome, 
    sum(Elemento.pegadaEcologica * composto.percentagem/100) AS eco
    FROM composto
    JOIN Produto
    ON composto.produto = Produto.codigo
    AND composto.prodMarca = Produto.marca 
    JOIN Elemento
    ON composto.elemento = Elemento.codigo
    GROUP BY composto.produto, composto.prodMarca) Eco
   ON compra.produto = Eco.produto AND compra.prodMarca = Eco.prodMarca
   GROUP BY compra.consumidor) Soma
ON Consumidor.numero = Soma.Consumidor

So now I have table like:

Consumidor.number Soma.soma 
123               90
456               70
789               70

Expected result should be Consumidor.number (-s) where Soma.soma is min.

I.e. for this table result should be:

Consumidor.number
456     
789

There's original schema for all tables used in this query:

Consumidor (PK numero, email, sexo, nascimento)
Elemento (PK codigo, nome, pegadaEcologica, saude)
Produto (PK codigo, FK PK Marca.numero marca, nome, tipo, comercioJusto)
compra (FK PK Produto.codigo produto, FK PK Produto.marca prodMarca, Consumidor.numero, quantidade)
composto (FK PK Produto.codigo produto, FK PK Produto.marca prodMarca, FK PK Elemento.codigo elemento, percentagem)

Update. I didnt stuck with solution - there is solution:

SELECT Consumidor.numero, Soma.soma
FROM Consumidor
JOIN
  (SELECT compra.consumidor, SUM(Eco.eco*compra.quantidade) as soma
   FROM compra
   JOIN
    (SELECT composto.produto, composto.prodMarca, Produto.nome, 
    sum(Elemento.pegadaEcologica * composto.percentagem/100) AS eco
    FROM composto
    JOIN Produto
    ON composto.produto = Produto.codigo
    AND composto.prodMarca = Produto.marca 
    JOIN Elemento
    ON composto.elemento = Elemento.codigo
    GROUP BY composto.produto, composto.prodMarca) Eco
   ON compra.produto = Eco.produto AND compra.prodMarca = Eco.prodMarca
   GROUP BY compra.consumidor) Soma
ON Consumidor.numero = Soma.Consumidor
WHERE Soma.soma <= ALL
  (SELECT SUM(Eco.eco*compra.quantidade) as soma
   FROM compra
   JOIN
    (SELECT composto.produto, composto.prodMarca, Produto.nome, 
    sum(Elemento.pegadaEcologica * composto.percentagem/100) AS eco
    FROM composto
    JOIN Produto
    ON composto.produto = Produto.codigo
    AND composto.prodMarca = Produto.marca 
    JOIN Elemento
    ON composto.elemento = Elemento.codigo
    GROUP BY composto.produto, composto.prodMarca) Eco
   ON compra.produto = Eco.produto AND compra.prodMarca = Eco.prodMarca
   GROUP BY compra.consumidor)

Simply put whole Soma query onto WHERE clause. With this im getting expected resault. But this looks so ugly and im looking for some more elegant way.

P.S. Don't throw tomatoes - following project statement I'm not able to use sub-queries in FROM clause, but if there are some observations about whole my code I will appreciate.

1

There are 1 answers

0
Володимир Кельбель On

So there is no really other way to solve it

SELECT Consumidor.numero
FROM compra
JOIN Consumidor
ON compra.consumidor = Consumidor.numero
JOIN
    (SELECT composto.produto, composto.prodMarca, Produto.nome, 
     sum(Elemento.pegadaEcologica * composto.percentagem/100) AS eco
     FROM composto
     JOIN Produto
     ON composto.produto = Produto.codigo
     AND composto.prodMarca = Produto.marca 
     JOIN Elemento
     ON composto.elemento = Elemento.codigo
     GROUP BY composto.produto, composto.prodMarca) Eco
ON compra.produto = Eco.produto AND compra.prodMarca = Eco.prodMarca
GROUP BY compra.consumidor
HAVING SUM(Eco.eco*compra.quantidade)<= ALL
    (SELECT SUM(Eco.eco*compra.quantidade)
     FROM compra
     JOIN Consumidor
     ON compra.consumidor = Consumidor.numero
     LEFT JOIN Dependente
     ON Dependente.consumidor = Consumidor.numero
     JOIN
        (SELECT composto.produto, composto.prodMarca, Produto.nome, 
         sum(Elemento.pegadaEcologica * composto.percentagem/100) AS eco
         FROM composto
         JOIN Produto
         ON composto.produto = Produto.codigo
         AND composto.prodMarca = Produto.marca 
         JOIN Elemento
         ON composto.elemento = Elemento.codigo
         GROUP BY composto.produto, composto.prodMarca) Eco
     ON compra.produto = Eco.produto
     AND compra.prodMarca = Eco.prodMarca
     GROUP BY compra.consumidor);

To get field with minimum value from current table you have to query this whole table in HAVING clause (check in which group SUM of compras less or equal of SUM of compras in ALL groups in current table). It can be marked as duplicate of any likely question.