首页 > 解决方案 > SQL Server 查询既返回具有外键的项目,也返回没有外键的项目

问题描述

我有一个折扣页面,我可以在其中添加应该有折扣价的产品。

每个产品都会在其下方显示许多产品变体,如果它们不应该成为折扣的一部分,则可以取消选中它们。

当我按下保存时,每个“CHECKED”ProductId 和 VariantId 将存储在一个名为 StoreDiscountRuleVariant 的表中。

如果打开现有折扣页面以进行编辑,则我的 SQL 查询不再从 ProductVariant 表中获取未选中的产品变体,而只获取已保存的“选中”产品。

我希望 SQL 查询既返回在表中具有匹配的 variantId 外键的 ProductVariants 也返回StoreDiscountRuleVariant没有的。我还需要一个额外的返回列来显示variantId 是否实际存在于StoreDiscountRuleVariant表中——例如isChecked=true/false。

我认为此解决方案比在保存后将已选中和未选中的 variantIds 存储在StoreDiscountRuleVariant表中要好,因为在进行此折扣后添加的新 ProductVariants 在编辑时不会显示。

我被指出这样做的方向:

 SELECT p.productid, pv.variantnameSE, pv.sku, pv.variantId, 
 rv.discountrulevariantid, rv.productvariantid FROM 
 dbo.StoreDiscountRuleVariant rv INNER JOIN dbo.Product p ON p.productId = 
 rv.productid LEFT JOIN dbo.productVariant pv ON pv.foreignProductId = 
 p.productId WHERE rv.discountruleid = 24 

结果如下:

第 1 行:

productid:1326,variantnamese:Vit,sku:FOD46-1,variant.variantid:822,discountrulevariantid:572,discountrulevariant.productvariantid:1035

第 2 行:

productid:1326,variantnamese:Svart,sku:FOD46-2,variant.variantid:1035,discountrulevariantid:572,discountrulevariant.productvariantid:1035

StoreDiscountRuleVariant 表中仅存在 ROW2/variantid: 1035。所以至少对我来说奇怪的是,discountrulevariantid 在两行上都指向 1035。不应该 ROW1 的 discountrulevariantid: value 为空,因为 variantid:822 在 StoreDiscountRuleVariant 中不存在。

标签: sqlsql-servertsql

解决方案


你需要一个LEFT JOIN. 目前尚不清楚您是想要所有产品还是所有存储的折扣规则变体

无论您想要哪个,那都应该是第一张桌子。根据该WHERE条款,我假设它是变体:

SELECT rv.productid, rv.productvariantid as variantid, 
       p.productnameSE as productname, pv.variantnameSE as variantname, 
       pv.sku, pv.ishidden, pp.picUrl, pp.picid 
FROM dbo.StoreDiscountRuleVariant rv LEFT JOIN
     dbo.Product p 
     ON p.productId = rv.productid LEFT JOIN
     dbo.productVariant pv
     ON pv.variantId = rv.productvariantid OUTER APPLY 
     (SELECT TOP (1) pp.* 
      FROM productpic pp 
      WHERE pp.productid = p.productid
      ORDER BY pp.isfrontpic DESC
     ) pp 
WHERE rv.discountruleid = 16 
ORDER BY rv.productid, pv.sortOrder;

OUTER APPLY那么对于横向连接是正确的。 CORSS APPLY--like INNER JOIN-- 将删除不匹配的变体。


推荐阅读