【问题标题】:Erase duplicates using substrings tsql使用子字符串 sql 擦除重复项
【发布时间】:2019-01-21 10:09:34
【问题描述】:

我有下表

create table bufScan
(
   msgid int,
   conversationid nvarchar(max),
   mailbox nvarchar(max)
);

INSERT dbo.bufScan VALUES 
(1,'person1@company.com','AAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMgAQAPX8hFCq30h3robsMxenwt8='),
(2,'person1@company.com','AAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMgAQAESPK731aUirpd0CyOIlR5I='),
(3,'person1@company.com','AAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMgAQAESPK731aUirpd0CyOIlR5I='),
(4,'person1@company.com','AAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMgAQAPX8hFCq30h3robsMxenwt8='),
(5,'person2@company.com','AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAQAPX8hFCq30h3robsMxenwt8='),
(6,'person2@company.com','AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAQAESPK731aUirpd0CyOIlR5I='),
(7,'person2@company.com','AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAQAESPK731aUirpd0CyOIlR5I='),
(8,'person2@company.com','AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAQAX8hFCq30h3robsMxenwt8=');

让我们假设AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMg 是为我们提供特定邮箱信息的条目,而AX8hFCq30h3robsMxenwt8=AESPK731aUirpd0CyOIlR5I= 是为特定对话提供信息的条目。

在此示例中,person1 正在与 person2 进行对话。 我希望只保留一个邮箱中的所有对话,否则就像在我的数据中进行双重对话一样。这意味着我想保留来自AAQkADhlYTk5MGY1LTJkOTUtNDVjNy1iNDg0LTljYjc5ODAzZTM3OQAAQkAGIwZjk4OTk4LTRkZGYtNDM5Yi04NGZlLTAzMDY1MjQ3ZjVlMgAX8hFCq30h3robsMxenwt8=AESPK731aUirpd0CyOIlR5I= 的条目。我希望我说得更具体。 由于我还想保留对话中所有邮件的信息,因此我不想删除邮箱同一分区中具有不同邮件 ID 的重复邮件。

【问题讨论】:

  • 如果那是一个表,列是什么样的?表的名称是什么?列的名称是什么?期望的结果也会很有帮助。
  • 编辑问题添加一些示例数据,期望的结果会有所帮助。
  • 如果邮箱3有zzz怎么办?
  • 这看起来仍然有重复,即“yyyAQA111”有两次,“yyyAQA222”也有。

标签: sql sql-server tsql


【解决方案1】:

你可以使用dense_rank()函数:

select top (1) with ties *
from table t
order by dense_rank() over (partition by substring(mailbox, 4, len(mailbox)) 
                                          order by conversationid);

【讨论】:

  • 您不能在 ORDER BY 子句中使用 DENSE_RANK() 并且您的查询还有其他语法问题。另外 - 这不考虑属性可以是不同长度的事实
  • @AlanBurstein。 . .你怎么能认为我们不能在order by 子句中使用分析函数?
  • 我的立场是正确的——这让我大吃一惊。自 SQL 2005 以来,我一直在 SQL Server 中使用窗口函数,并且从未在任何博客、论坛或书籍中看到它们在 order by 子句中使用。甚至 BOL 也没有这样的例子。取消投票,我今天学到了一些很酷的东西。太棒了,先生!
  • 谢谢@Yogesh Sharma,真的很有帮助!
  • @Yogesh Sharma,请看看我编辑的问题
【解决方案2】:

你的解释还是有点模糊。我认为这会奏效:

使用此示例数据:

USE tempdb
GO

create table dbo.bufScan
(
 msgid int,
 conversationid nvarchar(max),
 mailbox nvarchar(max)
 );

INSERT dbo.bufScan VALUES 
(1,'mailbox1','xxxAQA111'),
(2,'mailbox1','xxxAQA111'),
(3,'mailbox1','xxxAQA222'),
(4,'mailbox1','xxxAQA222'),
(5,'mailbox2','yyyAQA111'),
(6,'mailbox2','yyyAQA111'),
(7,'mailbox2','yyyAQA222'),
(8,'mailbox2','yyyAQA222');

你可以这样做:

WITH uniquify AS
(
  SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY f.conv ORDER BY (SELECT NULL))
  FROM dbo.bufScan
  CROSS APPLY 
    (VALUES (SUBSTRING(mailbox, PATINDEX('%[0-9]%', mailbox), LEN(mailbox)))) f(conv)
)
SELECT msgid, conversationid, mailbox
FROM uniquify
WHERE rn <= 2;

返回:

msgid       conversationid   mailbox
----------- ---------------- -----------
1           mailbox1         xxxAQA111
2           mailbox1         xxxAQA111
7           mailbox2         yyyAQA222
8           mailbox2         yyyAQA222

您可以将 rn

msgid       conversationid   mailbox
----------- ---------------- -----------
1           mailbox1         xxxAQA111
7           mailbox2         yyyAQA222

【讨论】:

    猜你喜欢
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多