【问题标题】:How to identify rows where two columns have match exactly in SQL Server [duplicate]如何识别 SQL Server 中两列完全匹配的行 [重复]
【发布时间】:2019-01-24 17:43:57
【问题描述】:

我的问题可能听起来很奇怪,但请多多包涵。这就是我所拥有的:

餐桌产品:


ProductName     Cost   
Pen A           1.00  
Pen A           1.00  
Pen B           1.00   
Pen A           2.00  
Pen C           3.00  
Pen C           3.00  
Pen C           3.00

如何从中删除真正的重复项?如果查看数据,您可以看到 Pen C 有三行数据完全相同。 Pen A 有 2 行数据相同,1 行成本不同。我不想消除“Pen A”。

这样一个简单的 group by 语句:

SELECT ProductName,Cost FROM PRODUCTS GROUP BY ProductName,Cost HAVING COUNT(*) > 1

这不起作用,因为它也会拾取“PEN A”。

感谢任何帮助。谢谢!

【问题讨论】:

  • 预期结果是什么?为什么SELECT DISTINCT ProductName,Cost FROM PRODUCTS 不返回你想要的?
  • 让这成为一个教训,始终在表中创建PRIMARY KEY

标签: sql sql-server


【解决方案1】:

不使用连接或子查询的快速方法是创建具有相同结构的表 PRODUCTS_TEMP 并仅插入唯一行:

INSERT INTO PRODUCTS_TEMP 
SELECT DISTINCT ProductName,Cost FROM PRODUCTS;

然后您可以删除您的 PRODUCTS 表并将 PRODUCTS_TEMP 重命名为 PRODUCTS:

DROP TABLE PRODUCTS;
ALTER TABLE PRODUCTS_TEMP RENAME TO PRODUCTS;

现在您的表格已过滤。

【讨论】:

  • * 注意我使用的是 Mysql 语法,因为我没有准备好测试的 sqlServer 实例。如果您发现任何不兼容性,请随时更新。
  • 如果适用,还需要记住编写 PK、FK、索引和触发器的脚本。如果需要其中任何一个,我会选择约翰的答案。
  • 不需要临时表,但我同意DISTINCT 是这里最简单的方法。
【解决方案2】:

您可以将CTERow_Number() 一起使用来删除 Dupes

示例

;with cte as (
    Select * 
          ,RN = Row_Number() over (Partition By ProductName,Cost Order By (Select null))
    from PRODUCTS 
)
Delete from cte where RN>1

更新表格

ProductName Cost
Pen A       1.00
Pen B       1.00
Pen A       2.00
Pen C       3.00

【讨论】:

    【解决方案3】:

    在以任何你喜欢的方式清理混乱之后,你可能想考虑用那 2 列创建一个约束索引和/或在插入新行之前验证以确保该组合不存在。

    祝你好运

    【讨论】:

      【解决方案4】:

      我认为您想要只有一种成本的产品。如果是这样:

      select productname
      from products
      group by productname
      having min(cost) = max(cost);
      

      【讨论】:

        猜你喜欢
        • 2021-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-27
        • 1970-01-01
        • 1970-01-01
        • 2017-11-07
        相关资源
        最近更新 更多