ROW_NUMBER()超过两列,如果,2行是相同的

时间:2017-08-08 06:28:34

标签: oracle greatest-n-per-group

我有这样的数据:

item_no p_no    date        RN()
35917   1220540 2000-04-03  1
35917   1220540 2000-04-18  1
35917   1220540 2001-02-12  1
35917   1220540 2001-03-08  1
35917   1220540 2001-03-19  1
542672  1243288 2000-01-24  1
564575  1243288 2000-01-24  2
549816  1243288 2000-01-24  3
542672  1243288 2000-02-25  1
564575  1243288 2000-02-25  2
549816  1243288 2000-02-25  3

我想为每个p_no选择一条记录,最大日期(最近的记录)。如果有2行具有相同的p_no和日期,我需要检查item_no并选择最高的记录。 例如:

  • p_no = 1243288有两个日期 - 2000-02-25和2000-01-24
  • 约2000-02-25是最伟大的所以记录日期= 2000-02-25是我正在寻找
  • 有3条记录具有相同的组(p_np,日期)所以我必须选择最大的item_no记录
  • 记录我感兴趣的是:

    564575 1243288 2000-02-25 2

我使用ROW_NUMBER()获取列RN

row_number() over (partition by p_no, date order by date desc) rnk,

但我不知道如何使用此列并检查item_no以选择我需要的内容。我的做法是错的吗? 有什么建议吗?

2 个答案:

答案 0 :(得分:0)

将item_no添加到行号功能的ORDER BY部分,使其变为ORDER BY date desc, item_no desc)。我们的想法是,如果日期相同,它会通过告诉哪个项目首先来打破分区中相同元素之间的联系

使用你的rnk:将你的整个select语句包含在另一个

SELECT * FROM ( <your select statement> ) WHERE rnk = 1

实施例

SELECT * FROM (

  select employee.*, row_number() over(partition by department order by salary desc) as rnk

) WHERE rnk = 1 --get highest paid in each dept

答案 1 :(得分:0)

考虑这个例子:

1我们复制你的表

 CREATE TABLE #tmp (
 item_no int
 ,p_no int
 ,[date] datetime
 )

2使用与您相同的数据填充

INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2000-04-03')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2000-04-18')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-02-12')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-03-08')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (35917,1220540,'2001-03-19')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (542672,1243288,'2000-01-24')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (564575,1243288,'2000-01-24')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (549816,1243288,'2000-01-24')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (542672,1243288,'2000-02-25')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (564575,1243288,'2000-02-25')
INSERT INTO #tmp (item_no,p_no,[date]) VALUES (549816,1243288,'2000-02-25')

3创建我们的选择语句

SELECT * FROM (
SELECT
    T.item_no
   ,T.p_no
   ,max(T.[date]) AS [max_date]
   ,row_number() OVER (PARTITION BY T.p_no ORDER BY T.item_no desc) AS rn
FROM
    #tmp AS T
GROUP BY
    T.item_no
   ,T.p_no
) AS A
WHERE
    rn = 1

首先我们找到最大日期。接下来,我们按照最高item_no的顺序对p_no进行分区,并为这些行赋值1.然后我们选择row_number = 1的所有内容。

编辑:更短/替代解决方案:

SELECT * FROM (
SELECT
    T.item_no
   ,T.p_no
   ,T.[date]
   ,row_number() OVER (PARTITION BY T.p_no ORDER BY T.[date] desc, T.item_no desc) AS rn
FROM
    #tmp AS T
) AS A
WHERE
    rn = 1