【问题标题】:SQL - Finding multiple duplicatesSQL - 查找多个重复项
【发布时间】:2018-03-11 11:18:10
【问题描述】:

我有一张产品表。这些产品具有产品 ID。产品 ID 可以由产品共享。它们由版本 ID 区分。例如,bike 的 id 为 1。有不同种类的自行车共享 p_id 为 1 但 v_id 为 1-15。表中有很多重复项,我想找到它们。我做了一个查询,找到产品的重复项。所以我可以看到产品的版本数,但有些产品被插入了两次。我写了一个查询来查看产品的版本计数,但现在我想查看所有重复项。有一列称为产品值(描述),如果它是重复的,它是指示符。

例子

productKey  productValue    cout
16293   Bike    2
16292   Bike    2
16291   Bike    2
16290   Pads    2
16289   Pads    2
16288   Helmet  3
16286   Shoe    2

从这里您可以看到自行车和护垫出现了 3 次,但头盔和鞋只出现了一次。我想编辑我的重复查询(或添加到其中),这样我就可以获得多次显示的项目(又名头盔和鞋子不会出现)第三列是版本,但可以忽略.

查询

SELECT productKey, productValue, COUNT(*) as cout
FROM [Store].[dbo].[products]
GROUP BY productKey, productValue
HAVING COUNT(*) > 1
ORDER BY productKey DESC

想要的结果,类似这样的

productKey  productValue    cout
16293   Bike    2
16292   Bike    2
16291   Bike    2
16290   Pads    2
16289   Pads    2

【问题讨论】:

  • 发布预期结果
  • cout 将是版本
  • 你写的查询似乎是正确的......问题是什么??
  • @Rams,它灌输了所有的产品。由于版本的原因,无论如何都会有重复的键。所以我写的查询找到了它们。它对 3 辆自行车之类的实际复制品没有任何作用。
  • 您正在尝试查询产品密钥及其版本的重复项,然后计算它们的数量?

标签: sql sql-server duplicates


【解决方案1】:

您想查找两个版本引用同一事物的产品。 (至少这是您的查询所做的。)从这些具有重复版本的产品中,您只想选择产品标题出现在至少两个有问题的产品中的那些产品。这似乎没有多大意义,但你去吧:

SELECT productKey, productValue, cout
FROM
(
  SELECT 
    productKey, 
    productValue, 
    COUNT(*) as cout,
    COUNT(*) OVER (PARTITION BY productValue) as cnt
  FROM Store.dbo.products
  GROUP BY productKey, productValue
  HAVING COUNT(*) > 1
) counted
WHERE cnt > 1
ORDER BY productKey DESC;

【讨论】:

  • 这真的很接近,它清除了一些不重复的,但仍然有一些(可能在幕后发生了其他事情)。我会看看我是否无法编辑此查询以完成删除这些重复项。
【解决方案2】:

使用Count() Over()窗口聚合函数

Select * from 
(
select *,
       cout = Count(1)over(partition by productValue)
from [Store].[dbo].[products]
) a
Wher cnt > 1

如果你想使用Group By,那么你需要sub-query

Select * 
from  [Store].[dbo].[products] 
where productValue in (SELECT productValue 
                       FROM [Store].[dbo].[products] 
                       GROUP BY productValue HAVING COUNT(*) > 1) 

【讨论】:

  • 是的,我认为当 John 认为可以基于他的查询来实现他想要的东西时,他是错误的。看来他真的只是在寻找重复的产品价值,所以你很好地忽略了他的阐述:-)
  • @ThorstenKettner - 是的,这就是我问他预期结果的原因。他要做的就是,如果productValue 多次出现,则返回它的所有记录
【解决方案3】:
You can select duplicate rows in subquery and select them in your main query



  SELECT 
         productKey, productValue,cout
    FROM 
         [Store].[dbo].[products] p1
    WHERE 
         productKey IN( 
               SELECT productKey
               FROM [Store].[dbo].[products]
               GROUP BY productKey, productValue
               HAVING COUNT(*) > 1
               )

【讨论】:

    【解决方案4】:

    给你:

    DECLARE @T TABLE (productKey INT, productValue VARCHAR(30), cout INT);
    INSERT INTO @T VALUES
    (16293,   'Bike',  2),
    (16292,   'Bike',  2),
    (16291,   'Bike',  2),
    (16290,   'Pads',  2),
    (16289,   'Pads',  2),
    (16288,   'Helmet',  3),
    (16286,   'Shoe',  2);
    
    SELECT *
    FROM @T
    WHERE  productValue IN (SELECT productValue FROM (SELECT productValue,COUNT(productValue) N FROM @T GROUP BY productValue) AS T WHERE T.N > 1) ;
    

    结果:

    +------------+--------------+------+
    | productKey | productValue | cout |
    +------------+--------------+------+
    |      16293 | Bike         |    2 |
    |      16292 | Bike         |    2 |
    |      16291 | Bike         |    2 |
    |      16290 | Pads         |    2 |
    |      16289 | Pads         |    2 |
    +------------+--------------+------+
    

    【讨论】:

      【解决方案5】:

      你真正想要的(根据我现在的理解):重复的产品名称,但忽略产品编号中的重复,因为这些是同一产品的版本,因此当然不被视为问题。

      因此,您正在寻找计算多个产品编号的产品名称。为此使用COUNT(DISTINCT ProductKey)

      select * 
      from
      (
        select products.*, count(distinct productkey) over (partition by productValue) as cnt
        from products
      ) counted
      where cnt > 1;
      

      【讨论】:

      • 我收到以下错误,“distinct”附近的语法不正确。我知道它说这在 sql 表单上是合法的,但我不能让它不给我这个错误。可能跟过度有关
      • 原来COUNT OVER在SQL Server中受到很大限制,不允许DISTINCT。但有一个惊人的解决方案。见这里:stackoverflow.com/questions/11202878/…
      【解决方案6】:

      请在SQL Query下方尝试,这可以帮助您实现结果:

      ;WITH CTE
           AS (
           SELECT productKey,
                  productValue,
                  COUNT(*) OVER(PARTITION BY productValue) AS ActualCnt
           FROM products
           GROUP BY productKey,
                    productValue)
           SELECT T.productKey,
                  T.productValue,
                  T.cout
           FROM CTE C
                INNER JOIN products T ON T.productValue = C.productValue
           WHERE C.ActualCnt > 1
           GROUP BY T.productKey,
                    T.productValue,
                    T.cout;
      

      期望的输出:

      productKey  productValue   cout
      ----------- ------------- -------
      16289       Pads           2
      16290       Pads           2
      16291       Bike           2
      16292       Bike           2
      16293       Bike           2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多