【问题标题】:How to return only 1 row if multiple duplicate rows and still return rows that are not duplicates?如果有多个重复行并且仍然返回不重复的行,如何仅返回 1 行?
【发布时间】:2009-09-18 02:28:31
【问题描述】:

我有一个看起来像这样的 temptable:

RequestID   | CreatedDate          | HistoryStatus           
CF-0000001  | 8/26/2009 1:07:01 PM | For Review   
CF-0000001  | 8/26/2009 1:07:01 PM | Completed  
CF-0000112  | 8/26/2009 1:07:01 PM | For Review   
CF-0000113  | 8/26/2009 1:07:01 PM | For Review  
CF-0000114  | 8/26/2009 1:07:01 PM | Completed  
CF-0000115  | 8/26/2009 1:07:01 PM | Completed   

而我希望表格最后的样子是这样的:

RequestID   | CreatedDate          | HistoryStatus           
CF-0000001  | 8/26/2009 1:07:01 PM | Completed  
CF-0000112  | 8/26/2009 1:07:01 PM | For Review  
CF-0000113  | 8/26/2009 1:07:01 PM | For Review  
CF-0000114  | 8/26/2009 1:07:01 PM | Completed  
CF-0000115  | 8/26/2009 1:07:01 PM | Completed

即应该删除重复的CF-0000001

如果有多个重复行并且仍然返回不重复的行,我该如何返回或者我应该说只选择一行?

【问题讨论】:

  • 两张表是一样的。请更正预期的输出。
  • RequestID 和 CreatedDate 相同时返回哪一行?还是没关系?
  • 我的解决方案假定日期实际上会有所不同,因此您可以选择最大日期 - 如果不是,需要一种方法来对状态进行排名以知道哪个应该获胜 - 虽然硬编码似乎不优雅......

标签: sql


【解决方案1】:

如果您想根据 RequestID 和 CreatedDate 显示重复行之一并显示最新的 HistoryStatus,请尝试此操作。

with t as (select row_number()over(partition by RequestID,CreatedDate order by RequestID) as rnum,* from tbltmp)
Select RequestID,CreatedDate,HistoryStatus from t a where  rnum in (SELECT Max(rnum) FROM t GROUP BY RequestID,CreatedDate having t.RequestID=a.RequestID)

或者,如果您想选择仅考虑 CreatedDate 的重复行之一并显示最新的 HistoryStatus,请尝试以下查询。

with t as (select row_number()over(partition by CreatedDate order by RequestID) as rnum,* from tbltmp)
Select RequestID,CreatedDate,HistoryStatus from t  where  rnum = (SELECT Max(rnum) FROM t)

或者,如果您想选择仅考虑请求 ID 的重复行之一并显示最新的 HistoryStatus,请使用下面的查询

with t as (select row_number()over(partition by RequestID order by RequestID) as rnum,* from tbltmp)
Select RequestID,CreatedDate,HistoryStatus from t a where  rnum in (SELECT Max(rnum) FROM t GROUP BY RequestID,CreatedDate having t.RequestID=a.RequestID)

以上所有查询都是我用sql server 2005写的。

【讨论】:

  • 好吧,当我试图复制粘贴您的示例代码时,我不小心对您投了反对票。 ...而且系统不允许我反转它,所以我改为“upvote”,这是你的好运:-)
【解决方案2】:

根据标题,我猜您每个唯一行只需要一个结果?如果是这种情况,请查看GROUP BY 子句(或SELECT DISTINCT)。

【讨论】:

    【解决方案3】:
    select t.*
    from (
        select RequestID, max(CreatedDate) as MaxCreatedDate
        from table1
        group by RequestID
    ) tm
    inner join table1 t on tm.RequestID = t.RequestID and tm.MaxCreatedDate = t.CreatedDate
    

    【讨论】:

    • 此查询将再次返回“重复项”。 CreatedDate 的值与RequestID = 'CF-0000001' 相同。
    • 虽然数据没有显示出来,但实际上我是假设时间会不同,否则如果没有硬编码就无法知道当有骗子时应该返回哪个状态.. .真的不是一个措辞很好的问题。
    【解决方案4】:

    如果您的查询中存在一对多关系,则一侧可能会出现重复行。

    假设如下

    TABLE TEAM
    ID       TEAM_NAME
    0        BULLS
    1        LAKERS
    
    
    TABLE PLAYER
    ID       TEAM_ID     PLAYER_NAME
    0        0           JORDAN
    1        0           PIPPEN
    

    然后你执行一个类似的查询

    SELECT 
        TEAM.TEAM_NAME, 
        PLAYER.PLAYER_NAME 
    FROM TEAM
    INNER JOIN PLAYER
    

    你会得到

    TEAM_NAME   PLAYER_NAME
    BULLS       JORDAN
    BULLS       PIPPEN
    

    因此,您将拥有重复的 TEAM NAME。即使使用 DISTINCT 子句,您的结果集也会包含重复的 TEAM NAME

    因此,如果您不想在查询中出现重复的 TEAM_NAME,请执行以下操作

    SELECT ID, TEAM_NAME FROM TEAM
    

    并且对于遇到的每个团队 ID 执行

    SELECT PLAYER_NAME FROM PLAYER WHERE TEAM_ID = <PUT_TEAM_ID_RIGHT_HERE>
    

    所以这样你就不会在一侧得到重复的引用

    问候,

    【讨论】:

      【解决方案5】:
      select * from temptable
      where rnum --unique key
       in 
      
      ( 
       SELECT RNUM --unique key
        FROM temptable
       WHERE (  HistoryStatus
      ) IN (SELECT                HistoryStatus
      
                                   FROM temptable
                                  GROUP BY                
      HistoryStatus 
                                 HAVING COUNT(*) <= 1));
      

      我没有测试过这段代码。我使用了类似的代码并且它有效。 语法在 Oracle 中。

      【讨论】:

        【解决方案6】:

        使用命名空间和子查询你可以做到:

        declare @data table (RequestID varchar(20), CreatedDate datetime, HistoryStatus varchar(20))
        insert into @data values ('CF-0000001','8/26/2009 1:07:01 PM','For Review');
        insert into @data values ('CF-0000001','8/26/2009 1:07:01 PM','Completed');  
        insert into @data values ('CF-0000112','8/26/2009 1:07:01 PM','For Review');   
        insert into @data values ('CF-0000113','8/26/2009 1:07:01 PM','For Review');  
        insert into @data values ('CF-0000114','8/26/2009 1:07:01 PM','Completed');  
        insert into @data values ('CF-0000115','8/26/2009 1:07:01 PM','Completed');
        
        select d1.RequestID,d1.CreatedDate,d1.HistoryStatus 
        from @data d1 
        where d1.HistoryStatus = 'Completed'
        union all 
        select d2.RequestID,d2.CreatedDate,d2.HistoryStatus 
        from @data d2 
        where d2.HistoryStatus = 'For Review' 
            and d2.RequestID not in (
                select RequestID 
                from @data 
                where HistoryStatus = 'Completed' 
                    and CreatedDate = d2.CreatedDate
            )
        

        以上查询返回

        CF-0000001, 2009-08-26 13:07:01.000,    Completed
        CF-0000114, 2009-08-26 13:07:01.000,    Completed
        CF-0000115, 2009-08-26 13:07:01.000,    Completed
        CF-0000112, 2009-08-26 13:07:01.000,    For Review
        CF-0000113, 2009-08-26 13:07:01.000,    For Review
        

        【讨论】:

          【解决方案7】:

          如果这是一个 SQL 问题,并且我理解您的要求,(不完全清楚),只需在查询中添加 distinct

             Select Distinct * From TempTable
          

          【讨论】:

          • 这对Chebu没有帮助,因为HistoryStatus中的值不同。
          【解决方案8】:

          要从两行的重复列中仅获取一条不同的记录,您可以使用由 oracle 本身维护的“rowid”列作为主键,所以首先尝试

          "select rowid,RequestID,CreatedDate,HistoryStatus  from temptable;"
          

          然后您只能通过在 SELECT 语句中使用“rowid”列的值来获取第二行。

          【讨论】:

          • 这假设是 Oracle,你如何“通过 rowid 的值获取第二行”?如果有人需要查看结果集以弄清楚那是什么,那不是一个非常有趣的“解决方案”。如果您知道如何编写执行此操作的查询(无需人工选择 rowid),请edit 您的问题。
          猜你喜欢
          • 1970-01-01
          • 2023-03-09
          • 1970-01-01
          • 1970-01-01
          • 2012-03-23
          • 2015-02-24
          • 1970-01-01
          • 1970-01-01
          • 2015-01-18
          相关资源
          最近更新 更多