Je suis aller chercher valeurs maximales par groupes (CTE data
émule un ensemble de jointures de tables réelles):Filtrage par RANK() dans la clause HAVING sans sous-requêtes
with data as (
select 'Austria' as country, 1 as id, 'red' as colour, 120 as quantity
union all select 'Austria', 2, 'green', 96
union all select 'Austria', 3, 'blue', 103
union all select 'Belgium', 1, 'red', 33
union all select 'Belgium', 2, 'green', 12
union all select 'Belgium', 3, 'blue', 40
)
select country, colour, quantity
from (
select country, colour, quantity,
rank() over (partition by country order by quantity desc, id) as position
from data
group by country, id, colour, quantity
) subquery
where position=1;
Cela fonctionne bien mais je m forcé d'envelopper la requête avec l'RANK()
appel dans un sous-requête, parce que cette alternative déclenche une erreur de syntaxe:
-- [...]
select country, colour, quantity,
rank() over (partition by country order by quantity desc, id) as position
from data
group by country, id, colour, quantity
having rank() over (partition by country order by quantity desc, id)=1;
Windowed functions can only appear in the SELECT or ORDER BY clauses.
Existe-t-il une syntaxe alternative pour éviter cette limitation ou la sous-requête est la seule manière sensée?
Le but ultime est d'intégrer ce code dans un plus grand ensemble d'expressions SQL générées dynamiquement. Si je peux garder une seule requête, je peux simplement définir les différentes parties (sélection, tables jointes, où, grouper par, avoir et ordonner par) avec des tableaux. Sinon, je dois penser à une réécriture majeure.
Plus 1, mais je pense que le groupe par pays, id, couleur, quantité est redondant – TriV
Oui, nous n'avons pas besoin de groupe par lequel est redondant –
Bien que top (1) avec des liens est plus élégant, il utilise un opérateur de tri supplémentaire qui est peu coûteux si vous avez un gros volume de données –