web-dev-qa-db-fra.com

Serveur SQL: comment utiliser une fonction d'agrégation comme MAX dans une clause WHERE

Je veux obtenir la valeur maximale pour cet enregistrement. Aidez-moi, s'il vous plaît:

SELECT rest.field1 
    FROM mastertable AS m
    INNER JOIN  (
        SELECT t1.field1 field1, 
               t2.field2
            FROM table1 AS T1 
            INNER JOIN table2 AS t2 ON t2.field = t1.field 
            WHERE t1.field3=MAX(t1.field3)
        --                  ^^^^^^^^^^^^^^  Help me here.
    ) AS rest ON rest.field1 = m.field
26
Geetha

Vous pouvez utiliser une sous-requête ...

WHERE t1.field3 = (SELECT MAX(st1.field3) FROM table1 AS st1)

Mais je déplacerais réellement ceci hors de la clause where et dans la déclaration join, en tant que AND pour la clause ON.

23
dlamblin

Comme vous l'avez remarqué, la clause WHERE ne vous permet pas d'y utiliser des agrégats. C'est à cela que sert la clause HAVING.

HAVING t1.field3=MAX(t1.field3)
38
Powerlord

La façon correcte d'utiliser max dans la clause having est d'effectuer d'abord une auto-jointure:

select t1.a, t1.b, t1.c
from table1 t1
join table1 t1_max
  on t1.id = t1_max.id
group by t1.a, t1.b, t1.c
having t1.date = max(t1_max.date)

Voici comment vous vous joindriez à une sous-requête:

select t1.a, t1.b, t1.c
from table1 t1
where t1.date = (select max(t1_max.date)
                 from table1 t1_max
                 where t1.id = t1_max.id)

Assurez-vous de créer un seul ensemble de données avant d'utiliser un agrégat lorsque vous traitez une jointure multi-table:

select t1.id, t1.date, t1.a, t1.b, t1.c
into #dataset
from table1 t1
join table2 t2
  on t1.id = t2.id
join table2 t3
  on t1.id = t3.id


select a, b, c
from #dataset d
join #dataset d_max
  on d.id = d_max.id
having d.date = max(d_max.date)
group by a, b, c

Version de la sous-requête:

select t1.id, t1.date, t1.a, t1.b, t1.c
into #dataset
from table1 t1
join table2 t2
  on t1.id = t2.id
join table2 t3
  on t1.id = t3.id


select a, b, c
from #dataset d
where d.date = (select max(d_max.date)
                from #dataset d_max
                where d.id = d_max.id)
7
metrix
SELECT rest.field1
FROM mastertable as m
INNER JOIN table1 at t1 on t1.field1 = m.field
INNER JOIN table2 at t2 on t2.field = t1.field
WHERE t1.field3 = (SELECT MAX(field3) FROM table1)
4
Tim Santeford

oui, vous devez utiliser une clause having après la clause Group by, où est juste de filtrer les données sur des paramètres simples, mais grouper suivi d'une instruction having est l'idée de regrouper les données et de les filtrer sur la base d'un agrégat une fonction......

1
Rohit

Mais cela donne toujours un message d'erreur dans Query Builder. J'utilise SqlServerCe 2008.

SELECT         Products_Master.ProductName, Order_Products.Quantity, Order_Details.TotalTax, Order_Products.Cost, Order_Details.Discount, 
                     Order_Details.TotalPrice
FROM           Order_Products INNER JOIN
                     Order_Details ON Order_Details.OrderID = Order_Products.OrderID INNER JOIN
                     Products_Master ON Products_Master.ProductCode = Order_Products.ProductCode
HAVING        (Order_Details.OrderID = (SELECT MAX(OrderID) AS Expr1 FROM Order_Details AS mx1))

J'ai remplacé WHERE par HAVING comme l'a dit @powerlord. Mais montrant toujours une erreur.

Erreur lors de l'analyse de la requête. [Numéro de ligne de jeton = 1, décalage de ligne de jeton = 371, jeton en erreur = SELECT]

0
Kamal