【问题标题】:get unique product from connectiontable with stored procedure使用存储过程从连接表中获取唯一产品
【发布时间】:2015-08-14 07:45:13
【问题描述】:

我有一个存储过程,我想通过连接表获取一些数据。数据库很旧,没有约束。

这是我的程序:

    select distinct(p.id), pd.language, p.Company, pd.shortDescription from dbo.Category c
    join dbo.ProductCategory pc on c.id = pc.CategoryId
    join dbo.Product p on pc.id = p.id
    join dbo.ProductDescription pd on p.id = pd.id
where
    c.Company = 'Normstahl' and 
    c.languageid = 'en' and 
    p.Company = 'Normstahl' and 
    pc.Company = 'Normstahl' and
    c.id != 'Deckenlauf' and 
    pd.language = 'en' and
    pd.Company = 'Normstahl'

如您所见,我想选择未连接到“Deckenlauf”类别的产品。

问题在于,如果一个产品与多个类别相关联,我无论如何都会收到与该类别相关联的产品,因为它只是跳过与该类别相关联的产品,但会找到与另一个类别相关联的相同产品.

 id CategoryId  Company
  1 Deckenlauf  Normstahl
  1 RGD_EUR9_DL Normstahl

这是来自类别和产品之间的连接表。因此,在我的存储过程中,我不想收到任何 id = 1 的产品,但现在我会收到,因为如果它没有连接到“Deckenlauf”类别,则需要第二行。如何在我的存储过程中解决这个问题?

【问题讨论】:

标签: mysql sql-server stored-procedures


【解决方案1】:

我是这样解决的:

 select distinct(p.id), pd.language, p.Company, pd.shortDescription from dbo.Category c
    join dbo.ProductCategory pc on c.id = pc.CategoryId
    join dbo.Product p on pc.id = p.id
    join dbo.ProductDescription pd on p.id = pd.id
where
    c.Company = @companyName and 
    c.languageid = @languageId and 
    p.Company = @companyName and 
    pc.Company = @companyName and
    c.id != @categoryId and 
    pd.language = @languageId and
    pd.Company = @companyName and
    p.id not in (select id from ProductCategory where CategoryId = @categoryId)

通过添加最后一个选择

【讨论】:

    【解决方案2】:

    我会尝试使用带有条件/过滤器和 WHERE IS NULL 的 LEFT JOIN 来检查产品是否有任何指向所选类别的链接。

    虽然您的子选择解决方案肯定会起作用并且可能更具可读性,但它应该会给您带来更好的性能。

    假设我已经了解您如何将输入参数用于存储过程,它会是这样的:

     LEFT JOIN dbo.ProductCategory pc on pc.id = p.id AND pc.CategoryId = @categoryId -- Only join for the chosen category
     WHERE pc.CategoryId IS NULL and -- Only include rows which did not "hit" the left join
    

    我已经更新了您的解决方案,并将我认为是加入条件的内容(即 pd.Company 和 pc.Company)移到了 ON 部分。

    此外,由于您似乎没有在选择中使用它,因此我已经删除了对 Category 的联接。

    给出以下查询:

     select distinct(p.id), pd.language, p.Company, pd.shortDescription 
     from  dbo.Product p 
        left join dbo.ProductDescription pd on p.id = pd.id AND pd.Company = p.Company AND pd.languageid = @languageId
        left join dbo.ProductCategory pc on pc.id = p.id AND pc.Company = p.Company AND pc.CategoryId = @categoryId 
      where pc.CategoryId IS NULL -- No matching category exists
        and p.Company = @companyName
    

    请注意,ProductDescription 的左连接用于在结果中包含行,即使对于提供的 @languageid 没有描述的产品也是如此,因为这就是您的解决方案中的查询的工作方式。 如果产品只有在有描述的情况下才应包含在结果中,则可以/应该将其更改为内部连接。

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 1970-01-01
      • 2012-02-24
      • 2016-08-14
      • 1970-01-01
      • 1970-01-01
      • 2021-10-22
      • 2018-03-04
      • 2012-07-28
      相关资源
      最近更新 更多