我有3张桌子。 BaseProducts,Products and ProductsMerchants。我需要使用条件找到计数。这是我的SQL,
ALTER PROCEDURE [dbo].[GetTotalProductsCount]
(
@SuperUser bit,
@MarchantId int
)
AS
BEGIN
IF(@SuperUser = 1)
BEGIN
SELECT COUNT(*) AS Total
FROM [dbo].[BaseProducts]
END
ELSE
BEGIN
SELECT COUNT(*) AS Total
FROM [dbo].[BaseProducts] BP
INNER JOIN [dbo].[Products] P ON P.BaseProductId = BP.Id
INNER JOIN ProductsMerchants PM ON PM.ProductId = P.Id
WHERE PM.MarchantId = @MarchantId;
END
END
问题是我需要重写相同的查询只是为了检查一个条件。我可以进行一次查询吗?
答案 0 :(得分:2)
你可以这样做:
SELECT COUNT(*) AS Total
FROM [dbo].[BaseProducts]
WHERE @SuperUser = 1
UNION ALL
SELECT COUNT(*) AS Total
FROM [dbo].[BaseProducts] BP
INNER JOIN [dbo].[Products] P ON P.BaseProductId = BP.Id
INNER JOIN ProductsMerchants PM ON PM.ProductId = P.Id
WHERE PM.MarchantId = @MarchantId AND @SuperUser <> 1;
就个人而言,我发现if
形式更容易理解。
如果inner join
用于过滤并且不增加行数,您还可以执行以下操作:
SELECT COUNT(*) AS Total
FROM [dbo].[BaseProducts] BP
LEFT JOIN [dbo].[Products] P ON P.BaseProductId = BP.Id
LEFT JOIN ProductsMerchants PM ON PM.ProductId = P.Id
WHERE PM.MarchantId = @MarchantId OR @SuperUser = 1;
(PM.MarchantId = @MarchantId
取消左外连接。)
但我再一次发现if
的意图更清晰。
甚至这个:
SELECT (CASE WHEN @SuperUser = 1 THEN CNT ELSE COUNT(*) END) AS Total
FROM (SELECT COUNT(*) as CNT FROM [dbo].[BaseProducts] BP) const CROSS JOIN
[dbo].[BaseProducts] BP
INNER JOIN [dbo].[Products] P ON P.BaseProductId = BP.Id
INNER JOIN ProductsMerchants PM ON PM.ProductId = P.Id
WHERE PM.MarchantId = @MarchantId OR @SuperUser = 1;