如何使用 window 函数获取最高价格及其 ID?

How do I use window function to get max price and its id?

我有这个问题

select adate, factoryid, purchid, itemname, max(price) as price 
from tableb where catnum = 9
group by adate, factoryid, purchid, itemname
order by adate, factoryid, purchid, itemname

但我想要该行的 ID。所以在一个完美的世界里:

select id, adate, factoryid, purchid, itemname, max(price) as price 
from tableb where catnum = 9
group by adate, factoryid, purchid, itemname
order by adate, factoryid, purchid, itemname

但我知道这行不通。

所以我尝试了这个:

select id, adate, factoryid, purchid, itemname, 
       max(price) over(partition by adate, factoryid, purchid, itemname) as price 
from tableb where catnum = 9

那是行不通的。所有 ID 的价格都是重复的。查询结果集从 4000 行增加到 11000 行。

很明显,我把 window 函数弄错了。首先,我做错了什么,其次,当然,我该如何解决?

SELECT  *
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (PARTITION BY adate, factoryid, purchid, itemname ORDER BY price DESC, id DESC) rn
        FROM    tableb 
        WHERE   catnum = 9
        ) q
WHERE   rn = 1

我不太清楚你为什么要这个 id 但是... 假设

  1. 您需要条件的所有 ID
  2. id是tableb的PK

那么这可能有效:

SELECT tableb.* FROM tableb
INNER JOIN
(
select adate, factoryid, purchid, itemname, max(price) as price 
from tableb where catnum = 9
group by adate, factoryid, purchid, itemname
) AS grouped
ON  tableb.adate = grouped.adate AND
    tableb.factoryid = grouped.factoryid AND
    tableb.purchid = grouped.purchid AND
    tableb.itemname = grouped.itemname AND
    tableb.price = grouped.price
order by tableb.adate, tableb.factoryid, tableb.purchid, tableb.itemname

您可以将 MAX 的窗口版本与 FIRST_VALUE 一起使用,可从 SQL Server 2012+ 获得:

SELECT DISTINCT adate, factoryid, purchid, itemname, 
       MAX(price) OVER (PARTITION BY adate, factoryid, purchid, itemname) AS price,
       FIRST_VALUE(id) OVER (PARTITION BY adate, factoryid, purchid, itemname
                             ORDER BY price DESC) AS id
FROM tableb 
WHERE catnum = 9
ORDER BY adate, factoryid, purchid, itemname