开发者

Select a row used for GROUP BY

开发者 https://www.devze.com 2023-03-12 07:30 出处:网络
I have this table: id | owner | asset | rate ------------------------- 1| 1| 3| 1 2| 1| 4| 2 3| 2| 3| 3 4| 2| 5| 4

I have this table:

id | owner | asset | rate
-------------------------
1  | 1     | 3     | 1
2  | 1     | 4     | 2
3  | 2     | 3     | 3
4  | 2     | 5     | 4

And i'm using

SELECT asset, max(rate)
FROM test 
WHERE owner I开发者_StackOverflow中文版N (1, 2)
GROUP BY asset
HAVING count(asset) > 1
ORDER BY max(rate) DESC

to get intersection of assets for specified owners with best rate.

I also need id of row used for max(rate), but i can't find a way to include it to SELECT. Any ideas?

Edit:

I need

  • Find all assets that belongs to both owners (1 and 2)
  • From the same asset i need only one with the best rate (3)
  • I also need other columns (owner) that belongs to the specific asset with best rate

I expect the following output:

id | asset | rate
-------------------------
3  | 3     | 3

Oops, all 3s, but basically i need id of 3rd row to query the same table again, so resulting output (after second query) will be:

id | owner | asset | rate
-------------------------
3  | 2     | 3     | 3

Let's say it's Postgres, but i'd prefer reasonably cross-DBMS solution.

Edit 2:

Guys, i know how to do this with JOINs. Sorry for misleading question, but i need to know how to get extra from existing query. I already have needed assets and rates selected, i just need one extra field among with max(rate) and given conditions if it's possible.


Another solution that might or might not be faster than a self join (depending on the DBMS' optimizer)

SELECT id, 
       asset,
       rate,
       asset_count
FROM (
    SELECT id,
           asset, 
           rate,
           rank() over (partition by asset order by rate desc) as rank_rate,
           count(asset) over (partition by null) as asset_count
    FROM test 
    WHERE owner IN (1, 2)
) t
WHERE rank_rate = 1
ORDER BY rate DESC


You are dealing with two questions and trying to solve them as if they are one. With a subquery, you can better refine by filtering the list in the proper order first (max(rate)), but as soon as you group, you lose this. As such, i would set up two queries (same procedure, if you are using procedures, but two queries) and ask the questions separately. Unless ... you need some of the information in a single grid when output.

I guess the better direction to head is to have you show how you want the output to look. Once you bake the input and the output, the middle of the oreo is easier to fill.


SELECT b.id, b.asset, b.rate
from
(
SELECT asset, max(rate) maxrate
FROM test  
WHERE owner IN (1, 2) 
GROUP BY asset 
HAVING count(asset) > 1 
) a, test b
WHERE a.asset = b.asset
AND a.maxrate = b.rate
ORDER BY b.rate DESC 


You don't specify what type of database you're running on, but if you have analytical functions available you can do this:

select id, asset, max_rate
from (
   select ID, asset, max(rate) over (partition by asset) max_rate, 
   row_number() over (partition by asset order by rate desc) row_num
   from test
   where owner in (1,2)
) q
where row_num = 1

I'm not sure how to add in the "having count(asset) > 1" in this way though.


This first searches for rows with the maximum rate per asset. Then it takes the highest id per asset, and selects that:

select  *
from    test
inner join
        (
        select  max(id) as MaxIdWithMaxRate
        from    test
        inner join
                (
                select  asset
                ,       max(rate) as MaxRate
                from    test 
                group by
                        asset
                ) filter
        on      filter.asset = test.asset
                and filter.MaxRate = test.rate
        group by
                asset
        ) filter2
on      filter.MaxIdWithMaxRate = test.id

If multiple assets share the maximum rate, this will display the one with the highest id.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号