【问题标题】:Removing duplicates from SQL query in One to many relationship在一对多关系中从 SQL 查询中删除重复项
【发布时间】:2015-07-24 23:45:48
【问题描述】:

我的表关系如下:

表 1 -> 表 2(DB 中的一对多关系)

如果我对表 1 进行以下查询:

select *
from table1 as t1
where t1.id = 1 

我将只从该表中获取特定记录的一条记录,但如果我确实加入表 2,如下所示:

    select *
    from table1 as t1
    join table2 as t2
    on t1.id = t2.id
    where t1.id=1

如果我在表 2 中多次插入表 1 中的 ID,这次我将获得多条记录。现在的问题是,在查询中执行此联接后,有没有办法仅显示 1 条记录,以一对多关系??

有人可以帮我解决这个问题吗?谢谢!

我使用了koppinjo的方式,现在查询如下:

SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( PARTITION BY PC.SubCategoryID 
                                     ORDER BY PC.[SubCategoryID] ) AS [Row]
                   ,sc.*
                   ,pc.MeasurementQuantity
                   ,pc.Price
                   ,pc.ProductCategoryID
                   ,pc.ProductID
                   ,p.Dimensions
                   ,p.FileName
                   ,p.ProductDescription
                   ,p.ProductName
                   ,mu.Unit
          FROM      SubCategory AS sc
                    JOIN ProductsCategories AS pc ON sc.SubCategoryID = pc.SubCategoryID
                    JOIN Products AS p ON p.ProductID = pc.ProductID
                    JOIN MeasurementUnits AS mu 
                          ON mu.MeasurementUnitID = p.MeasurementUnitID
          WHERE     pc.SubCategoryID = 1
        ) AS t
WHERE   t.[Row] = 1

现在的问题是,查询只返回 1 个结果。但是如果有两个产品属于同一类别呢?

附:我忘了提到这个查询的实际数据库架构是:

产品 -> ProductsCategories

假设 2 个产品属于两个类别,我需要同时获取这两个产品,但不能重复。 Koppinjo 的方式只返回 1 个结果...

【问题讨论】:

  • 您会获得多条记录,因为有多条记录符合您的标准。 sql serevr 如何知道从 table2 获取什么值?您需要提供一个条件来过滤 table2 中与 t1.id 具有相同 id 的行。
  • 就像 Zohar Peled 所说,您需要告诉表 2 中您想查看的行。例如,您想查看表 2 中的第一行吗?还是最大的价值?您需要提供一个条件来过滤行,或者进行分组或类似的操作。

标签: sql-server sql-server-2008 tsql sql-server-2012 sql-server-2014


【解决方案1】:

我建议使用像 ROW_NUMBER() 这样的窗口函数。例如:

SELECT *
FROM (
      SELECT
          ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.[primary/unique key]) AS [row]
         ,t1.*
      FROM table1 t1
          JOIN table2 t2 ON t1.id = t2.id
      WHERE t1.id = 1
     ) t
WHERE t.[row] = 1

这样的事情应该会让你指向正确的方向。希望对您有所帮助!

【讨论】:

  • 您能否查看我更新的问题。我用过你的方法,但不是 100% 有效,我不知道为什么......
  • 尝试将 ORDER BY 列(在查询的 PARTITION BY 部分中)更改为 PC.[SubCategoryID] 以外的其他内容。通常,您希望按创建日期或 orderId 之类的东西进行排序 - 具有自然基数的东西。
  • 我改了,还是只返回1个结果...问题是,如果两个不同的产品在同一个子类别下怎么办?此查询一次只返回一个产品,但是如何显示它们(如果同一类别下有两个产品)。这是多对多的关系...
  • 可能是由于您的代码中的原因:“where pc.SubCategoryID=1”?如果没有很好地掌握您的数据,我很难就如何构建 ROW_NUMBER() 函数提出建议。如上所示,您将数据按 SubCategoryId 分组,然后对它们进行排名并返回前 1,这就是为什么您只得到一个结果的原因。可能需要在 ROW_NUMBER() 函数中进行一些调整。
【解决方案2】:

您可以使用 distinct 并且不显示 table2 中的任何列。比如:

select distinct t1.*
from table1 as t1
join table2 as t2
on t1.id = t2.id
where t1.id=1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-03
    • 1970-01-01
    • 2019-12-11
    • 1970-01-01
    • 2013-07-23
    • 2021-03-14
    • 1970-01-01
    • 2015-02-21
    相关资源
    最近更新 更多