通过对它们进行分组来获取重复的 Id

Posted

技术标签:

【中文标题】通过对它们进行分组来获取重复的 Id【英文标题】:Get duplicated Ids by grouping them 【发布时间】:2021-12-17 05:26:21 【问题描述】:

我需要检索所有应该重试的事务,具体取决于事务接收到的消息,例如,如果我们收到诸如“超时”之类的错误消息,则该事务需要进行第二次尝试。所有交易都存储在一个表中,这意味着如果支付 id 重复,则表示该交易进行了重试,但也有不会发生这种情况的情况。

我编写了一个查询,它使用错误消息提取事务并将它们分组 通过付款 ID,查询有效,但它也带来了第二次尝试的交易。

我做错了什么?

   | payment_id | Bank  | time_requested | issuer      | message |attempt| 
   |   10369    | Citi  | 2021-08-03     | Capital One | success |   1   |
   |   10383    | HSBC  | 2021-07-07     | Discover    | success |   1   |
   |   84530    | HSBC  | 2021-07-07     | Visa        | timeout |   1   |
   |   84530    | HSBC  | 2021-07-07     | Visa        | success |   2   |
   |   53030    | Citi  | 2021-07-07     | Diners      | success |   1   |
   |   23930    | Citi  | 2021-07-07     | Diners      | timeout |   1   |

   select payment_id, count(payment_id) as times
   from paymentstbl
   where message in ('timeout', 'disconnected','unknown', 'Unavaialble')
   group by payment_id
   having times =1 

   Results:

   |   payment_id    | times  | 
   |    84530        | 1      |-- Wrong. Id 84530 is twice in the table
   |    23930        | 1      |-- Correct. 

【问题讨论】:

但是第二个有 messagesuccess 并且您排除了 success 消息:) 【参考方案1】:

看来您实际上并不关心计数,实际要求是识别未成功的付款。如果这是真的,您可以通过识别每个 payment_id 的最后一行来做到这一点。

SELECT DISTINCT pt2.*
FROM paymentstbl pt1
INNER JOIN paymentstbl pt2 ON pt2.payment_id = pt1.payment_id AND
                              pt2.attempt = (SELECT MAX(attempt)
                                             FROM paymentstbl
                                             WHERE payment_id = pt1.payment_id)

获得最后一行后,您可以过滤它们以仅包含具有您已知错误消息之一的那些。

WHERE pt2.message IN ('timeout', 'disconnected', 'unknown', 'Unavaialble')

或者,您可以排除那些成功的。

WHERE pt2.message != 'success'

【讨论】:

【参考方案2】:

如果您正在查找带有错误消息但没有成功付款的交易。如果是,您可以尝试以下查询。

SELECT * from paymentstbl WHERE PAYMENTID NOT IN
(
    SELECT payment_id FROM paymentstbl WHERE message IN ('timeout', 'disconnected', 'unknown', 'Unavaialble')
    INTERSECT
    SELECT payment_id FROM paymentstbl WHERE message= 'success'
)
and MESSAGE IN ('timeout', 'disconnected', 'unknown', 'Unavaialble')

Intersect 将把成功和超时/错误的paymentid放在一起。

现在过滤它们以仅包括那些有超时/错误付款的人。

【讨论】:

【参考方案3】:

我认为,通过 give or when do where 子句可以解决你的问题。

select payment_id, count(payment_id) as times
   from paymentstbl
   where message in ('timeout', 'disconnected','unknown', 'Unavaialble') or attempt > 1
   group by payment_id
   having times =1 

【讨论】:

OP 认为结果应该是 84530 | 2 因为他们没有意识到第二个 84530 有一个 message = success 不包括在选择中,请参阅 where message in ('timeout', 'disconnected','unknown', 'Unavaialble') 你的输出甚至没有包括计数,仅包括总数为 1 的那些。我认为您可能误读了这个问题 是的,谢谢指正

以上是关于通过对它们进行分组来获取重复的 Id的主要内容,如果未能解决你的问题,请参考以下文章

按id typescript对对象数组进行分组[重复]

mysql中删除重复数据

分组顺序重复值 sqlite

C# 属性列表。需要根据2个条件对它们进行分组[重复]

在熊猫数据框中对重复的列 ID 进行分组

如何对 BigQuery 中的重复字段进行分组