Question

This query gets the top item in each group using the ranking function.

I want to reduce the number of inner selects down to two instead of three. I tried using the rank() function in the innermost query, but couldn't get it working along with an aggregate function. Then I couldn't use a where clause on 'itemrank' without wrapping it in yet another select statement.

Any ideas?

select *
from (
    select 
        tmp.*,
        rank() over (partition by tmp.slot order by slot, itemcount desc) as itemrank
    from (
        select
            i.name, 
            i.icon,
            ci.slot,
            count(i.itemid) as itemcount
        from items i
        inner join citems ci on ci.itemid = i.itemid
        group by i.name, i.icon, ci.slot    
    ) as tmp
) as popularitems
where itemrank = 1

EDIT: using sql server 2008

Was it helpful?

Solution

In Oracle and Teradata (and perhaps others too), you can use QUALIFY itemrank = 1 to get rid of the outer select. This is not part of the ANSI standard.

OTHER TIPS

You can use Common Table Expressions in Oracle or in SQL Server.

Here is the syntax:

WITH expression_name [ ( column_name [,...n] ) ]
AS
( CTE_query_definition )

The list of column names is optional only if distinct names for all resulting columns are supplied in the query definition.

The statement to run the CTE is:

SELECT <column_list>
FROM expression_name;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top