【问题标题】:How to remove duplicate rows from a join query in oracle? [closed]如何从oracle中的连接查询中删除重复的行? [关闭]
【发布时间】:2020-06-24 07:19:01
【问题描述】:

我有两个表 bc_transactions 和 bc_messages。我使用下面的查询来加入这两个表

SELECT distinct(bt.USER_TRANS_ID),bm.TS,bm.STATUS
FROM bc_transactions bt
inner JOIN bc_messages bm
ON bt.USER_TRANS_ID=bm.USER_MESSAGE_ID
where bt.protocol_name  = 'Gateway'
and bt.STATUS=bm.STATUS
AND bt.startdate >=TRUNC(SYSDATE-2)
AND bt.startdate <=TRUNC(SYSDATE-1)
AND bt.STATUS like 'ERROR TRANSPORT'
AND bt.HOSTNAME='HEB'
order by bt.USER_TRANS_ID ASC;

bc_messages 表有多个状态为 ERROR TRANSPORT 的行,它们在不同的时间戳 (bm.TS) 具有相同的 USER_MESSAGE_ID。我试图只获取最新的行。

|USER_TRANS_ID |            TS        |   STATUS            |
-------------------------------------------------------------
| ID1          | 10-03-2020  15:01:23 |   ERROR TRANSPORT   |
| ID1          | 10-03-2020  15:15:23 |   ERROR TRANSPORT   |
| ID1          | 10-03-2020  15:30:23 |   ERROR TRANSPORT   |
| ID1          | 10-03-2020  15:35:23 |   ERROR TRANSPORT   |
| ID2          | 10-03-2020  16:10:23 |   ERROR TRANSPORT   |
| ID2          | 10-03-2020  16:11:23 |   ERROR TRANSPORT   |

【问题讨论】:

  • Fetch the row which has the Max value for a column 这是一个常见问题解答。在考虑发布之前,请阅读手册和谷歌任何错误消息或您的问题/问题/目标的许多清晰、简洁和精确的措辞,有和没有您的特定字符串/名称和站点:stackoverflow.com 和标签;阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。

标签: sql oracle outer-join


【解决方案1】:

您可以使用row_number()

select t.*
from (select bt.USER_TRANS_ID, bm.TS,bm.STATUS,
             row_number() over (partition by bt.USER_TRANS_ID order by bm.TS desc) as seq
      from bc_transactions bt inner join
            bc_messages bm
            on bt.USER_TRANS_ID = bm.USER_MESSAGE_ID
       where bt.protocol_name  = 'Gateway' and 
             bt.STATUS=bm.STATUS and 
             bt.startdate >= TRUNC(SYSDATE-2) and 
             bt.startdate <= TRUNC(SYSDATE-1) and 
             bt.STATUS like 'ERROR TRANSPORT' and 
             bt.HOSTNAME = 'HEB'
     ) t
where seq = 1;

【讨论】:

  • 非常感谢@Yogesh Sharma。解决了我的问题
【解决方案2】:

您可以使用ROW_NUMBER解析函数如下:

SELECT USER_TRANS_ID, TS, STATUS FROM 
(SELECT bt.USER_TRANS_ID,bm.TS,bm.STATUS, 
ROW_NUMBER() OVER (PARTITION BY bt.USER_TRANS_ID , bm.STATUS 
                   ORDER BY bm.TS DESC NULLS LAST) AS RN -- added this
FROM bc_transactions bt
inner JOIN bc_messages bm
ON bt.USER_TRANS_ID=bm.USER_MESSAGE_ID
where bt.protocol_name  = 'Gateway'
and bt.STATUS=bm.STATUS
AND bt.startdate >=TRUNC(SYSDATE-2)
AND bt.startdate <=TRUNC(SYSDATE-1)
AND bt.STATUS like 'ERROR TRANSPORT'
AND bt.HOSTNAME='HEB')
WHERE RN = 1 -- added this
order by bt.USER_TRANS_ID ASC;

干杯!!

【讨论】:

    【解决方案3】:

    使用group by获取最大时间戳

    select
         bt.USER_TRANS_ID,max(bm.TS),bm.STATUS
     FROM
         bc_transactions bt
         inner JOIN bc_messages bm ON bt.USER_TRANS_ID=bm.USER_MESSAGE_ID
     where
         bt.protocol_name  = 'Gateway'
         and bt.STATUS=bm.STATUS<br>
         AND bt.startdate >=TRUNC(SYSDATE-2)
         AND bt.startdate <=TRUNC(SYSDATE-1)
         AND bt.STATUS like 'ERROR TRANSPORT' // its better to keep status without space
         AND bt.HOSTNAME='HEB'
     group by
         bt.USER_TRANS_ID,bm.STATUS
     order by bt.USER_TRANS_ID ASC;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多