有条件地加入表格

时间:2014-05-01 11:46:32

标签: sql sql-server sql-server-2012

我有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

问题是我需要重写相同的查询只是为了检查一个条件。我可以进行一次查询吗?

1 个答案:

答案 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;