ROW_NUMBER()超过两列,如果两行相同,则

ROW_NUMBER()超过两列,如果两行相同,则

问题描述:

我的数据是这样的:ROW_NUMBER()超过两列,如果两行相同,则

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和date,我需要检查item_no并选择最高的记录。 例子:

  • p_no = 1243288有两个dates- 2000年2月25日和2000年1月24日
  • 日期2000年2月25日是GREATEST所以用最新记录= 2000年2月25日是什么我'看
  • 有3条记录与同组(p_np,日期),所以我不得不选择具有最大ITEM_NO
  • 记录我的兴趣与记录:

    564575 1243288 2000年2月25日2

我用ROW_NUMBER()来获取列RN

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

,但我不知道如何使用此列,并检查ITEM_NO选择我需要什么。我的方法是错误的吗? 有什么建议吗?

+0

只需在分析函数的'order by'子句中添加'ITEM_NO desc'。顺便说一句,如果你使用12c [检查这个答案](https://stackoverflow.com/a/43028479/146325) – APC

将item_no添加到行号功能的ORDER BY部分,以便它变成ORDER BY date desc, item_no desc)。我们的想法是,它告诉该产品是第一位的,如果日期是相同的

要使用您的RNK的破坏分区中的相同元素之间的配合:包裹内的另一个

SELECT * FROM (<your select statement>) WHERE rnk = 1 
你的整个select语句

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我们复制你的表

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语句

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

EDIT一切:较短/替代的解决方案:

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 
+0

这似乎是一个非常复杂的方式来实现目标;通过向分析函数顺序子句添加项目号,它提供了什么? –

+0

实现同一目标的许多方法。 – ssn