我想在T-SQL查询中为表创建条件连接。此示例中使用的表来自Northwind数据库(只有一个附加表ProductCategories)
表产品和表类别具有多对多关系,因此表ProductCategories即将出现。
对于属于特定类别的每个产品,我需要表OrderDetails上的Quantity列总和。所以我有一个像下面的查询
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
Join ProductCategories pc On pc.ProductID = p.ProductID
And pc.CategoryID = @CategoryID
Group By p.ProductName
@CategoryID是一个可选参数。因此,如果未提供,则不需要加入表ProductCategories 和查询应该如下所示
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
Group By p.ProductName
我希望在不使用If条件(如下所示)重复整个查询的情况下实现此目的
If @CategoryID Is Null
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
Group By p.ProductName
Else
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
Join ProductCategories pc On pc.ProductID = p.ProductID
And pc.CategoryID = @CategoryID
Group By p.ProductName
这是查询的简化版本,其中包含许多其他表和条件,如ProductCategories。并且将需要多个If条件并重复查询。我也试过动态生成查询。它有效但查询根本不可读。
任何解决方案? 谢谢。
答案 0 :(得分:2)
试试这个,如果你使用正确的参数化查询 - 不会对性能产生影响,但可能会有所收获:
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
WHERE @CategoryID IS NULL OR EXISTS (SELECT * FROM ProductCategories WHERE CategoryID = @CategoryID AND ProductID = p.ProductID)
Group By p.ProductName
<强>实际上强>
在您的查询中如果ProductCategories
中的OrderDetails
中的一行中有多行,那么您在SUM中会得到od.Quantity
的重复项 - 是否是预期的行为吗
答案 1 :(得分:0)
我对T-SQL不太熟悉所以我不知道这是否会削减它,但在mysql中你可以做类似的事情
Select p.ProductName, Sum(od.Quantity) As Qty
From Products p
Join OrderDetails od On od.ProductID = p.ProductID
Join ProductCategories pc On pc.ProductID = p.ProductID
And pc.CategoryID = if(@CategoryID is null , pc.CategoryID, @CategoryId)
Group By p.ProductName
是的,if()仍然存在但只是“一个查询”,如果这就是你要找的东西。
同时,您说您能够动态生成单个查询。如果是可读性那么大问题呢?如果您生成的查询比我上面提到的更符合我的意思,那么我会选择它。它是生成的;你赢了'手动调整/读取结果。
答案 2 :(得分:0)
我相信你可以加入表格与你正在进行的隐式内部联接。
在内连接中,它将源表上的键与目标表上的每个键实例匹配。
目标表上的每个匹配实例都会生成一组显示的行 匹配类型。
使用外部联接,它将显示源行,如果另一个表中没有匹配的行。如果存在它将基本上与内连接相同,并且您将为每个匹配实例返回一行。因此,您可以获得所需的数据,而不是获取哪些数据不可用。
以此为例
select * from Products
Left join ProductAndCategory on ProductAndCategory.ProductID = Products.ProductID
left join Categories on Categories.CategoryID = ProductAndCategory.CategoryID
我有一个简单的Product
表格,其中包含ProductID
和ProductName
一个ProductAndCategory
表格,其中包含ProductID
和CategoryID
以及Categories
表格CategoryID
和CategoryName
它将显示具有已连接类别的类别的行,而没有类别的行将仅显示对于不存在的值为null的一行。