【问题标题】:SQL- selecting between duplicate rows by comparing field valuesSQL-通过比较字段值在重复行之间进行选择
【发布时间】:2018-04-10 11:20:11
【问题描述】:

我想知道是否有人可以帮助我。 我已经设法只插入不重复的行

NSERT INTO temp_Log  
SELECT dq1.RowID,dq1.Action FROM DQLog dq1
    WHERE dq1.RowID 
    NOT IN (SELECT RowID FROM DQLog dq2
                group by dq2.RowID
                having count(*)>1

我仍然需要过滤重复的... 如何通过比较同一表中重复行之间的值来选择一行?

RowID  Action 
 1     Reject
 1     Allow
 2     Allow
 2     Fix

在这种情况下,我只需要插入第一行 (reject+allow= Reject) 和最后一行 (Allow+Fix = Fix)。

感谢大家的宝贵时间。

【问题讨论】:

  • Action 是否存在其他组合?例如reject+fix 或其他什么?
  • 我有 3 个操作(拒绝、允许、修复)但是拒绝将否决所有并修复否决允许,如果 2 行有“允许”,那么我可以选择其中一个。
  • 当 aRowIDRejectFix 作为操作时会发生什么?这是一个可能的场景吗?如果是,那么应该插入哪个动作?
  • 这只是 dqlog 表。一旦 dqlog 表完成,合并将处理正确的操作。现在的操作只是以后的标志。
  • 好的。但假设 RowId 3 有 t 个操作。1)拒绝和 2)修复。在这种情况下,应该与 RowId 3 一起插入哪个 Action?拒绝还是修复?

标签: mysql sql insert duplicates data-warehouse


【解决方案1】:

我会这样说:

INSERT INTO temp_Log (?, ?)  -- put the column names here
    SELECT dq1.RowID,
           (CASE WHEN MIN(dq1.Action) = MAX(d1.Action) THEN MIN(dq1.Action)
                 WHEN SUM(dq1.Action = 'Allow') > 0 AND SUM(dq1.Action = 'Reject') > 0 THEN 'Reject'
                 WHEN SUM(dq1.Action = 'Allow') > 0 AND SUM(dq1.Action = 'Fix') > 0 THEN 'Fix'
                 ELSE ??  -- your rules don't specify
           END) as Action
    FROM DQLog dq1
    WHERE NOT EXISTS (SELECT 1
                      FROM DQLog d12 
                      WHERE dq1.RowID = dq2.RowID
                     )
GROUP BY dq1.RowId;

注意事项:

  • 在插入时列出列。这是一种最佳做法,可以防止将来出现编码错误。
  • 这包括您指定的两个规则。但是,还有其他情况您没有指定。因此,ELSE ??.
  • NOT EXISTS 优于 NOT IN 有两个原因。首先,如果子查询中有一行是NULLNOT IN 将过滤掉所有行。其次,NOT EXISTS 应该比聚合子查询更快。

【讨论】:

  • 谢谢戈登,我会试试看的!
  • 是的......我猜 sum() 在这里工作正常。从来没有想过这种方法。 (+1 来自我)。
【解决方案2】:

如果 Row_ID 不可能多次将 Allow as Action 作为操作,则以下查询应该有效:

INSERT INTO temp_Log  
(SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'Reject'
UNION ALL
SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'Fix'
And RowID not in (Select distinct RowID from DQLog where Action='Reject')
)
;

编辑:

我在评论中提到了 2 个选项。它是怎么回事:

选项 1:

将操作列转换为小写值。

Update DQLog set Action = Lower(Action);

上述查询会将Action 的所有值转换为小写。现在您可以运行以下查询并完成:

INSERT INTO temp_Log  
(SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'reject'
UNION ALL
SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'fix'
And RowID not in (Select distinct RowID from DQLog where Action='reject')
)
;

因此您的任务已完成,您的冗余数据也已修复。

Option 2:

只需在我的主查询的 where 子句中添加 FixReject 的所有可能变体,如下所示:

INSERT INTO temp_Log  
(SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'Reject' or Action='reject'
UNION ALL
SELECT distinct RowID,Action           
FROM DQLog 
Where Action = 'Fix' or Action = 'fix'
And RowID not in (Select distinct RowID from DQLog where Action='Reject'or Action='reject')
)
;

我会建议你去Option 1

希望对您有所帮助!

【讨论】:

  • 我现在试试,我会告诉你的!谢谢老兄!
  • 我的 microsoft sql server management studio 说 group_concat 不是公认的内置函数。我会尝试找到通讯员的,但谢谢队友。它已经给了我一个想法
  • Microsoft Sql 服务器?您已标记 MySql 好友。这就是我使用 Group_Concat 的原因。请正确标记 RDBMS。
  • 与Oracle或MySQL相比,sql server中的任务很难。你能告诉我你的Sql服务器的版本吗?我可以找到相应的解决方案。
  • 抱歉打错标签了,下次不会了。感谢您解决该错误。
猜你喜欢
  • 1970-01-01
  • 2019-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多