SQL查询的WHERE子句中的CASE语句。有点复杂的COUNT子句

时间:2011-12-20 20:41:14

标签: sql sql-server case clause

这是在sql server 2005中。我有两个表:customersorders。有一个存储过程有一个参数minimumorders(0或大于零是可能的值)。我想避免像上面这样的IF ELSE块,并使用CASE语句。有没有办法在CASE子句中使用WHERE语句来避免代码中的IF ELSE块?目前IF&上有5行。重复ELSE个块。我不希望他们重复。我期待着如下的查询。

CREATE PROC STOREDPROC1
@MinimumOrders  INT AS IF @MinimumOrders = 0
BEGIN
    SELECT 
        CUSTOMERID 
        , (SELECT COUNT(ORDERID) FROM ORDERS O WHERE O.CUSTOMERID = C.CUSTOMERID) AS ORDERS
        FROM CUSTOMER C
ENDELSE IF @MinimumOrders = 1
BEGIN
    SELECT 
        CUSTOMERID 
        , (SELECT COUNT(ORDERID) FROM ORDERS O WHERE O.CUSTOMERID = C.CUSTOMERID) AS ORDERS
        FROM CUSTOMER C
            WHERE (SELECT COUNT(ORDERID) FROM ORDERS O WHERE O.CUSTOMERID = C.CUSTOMERID) > 0
END     

我需要一些CASE语句,如下所示。不幸的是,它不适合我。

-------------------- 12/20/2011 -- 11:52:34 AM -- Tuesday -------------------- 
    SELECT 
        CUSTOMERID 
        , (SELECT COUNT(ORDERID) FROM ORDERS O WHERE O.CUSTOMERID = C.CUSTOMERID) AS ORDERS
        FROM CUSTOMER C
        AND C.customerid=
            CASE @MiniumOrders
                WHEN 0 THEN C.CustomerID
                WHEN 1 THEN 
                    CASE  ( Select COUNT(O.CustomerID) FROM Orders O where O.Customerid = C.customerid    ) 
                        WHEN 0 THEN 0   -- customer id = 0 means no match
                            ELSE C.CustomerID
                    END 
                END 
        -------------------- 12/20/2011 -- 11:52:34 AM -- Tuesday -------------------- 

2 个答案:

答案 0 :(得分:2)

考虑使用join和HAVING子句:

SELECT
    C.Customer_ID,
    COUNT(O.Customer_ID) AS Orders
FROM
    Customers C
    LEFT JOIN Orders O
        ON C.Customer_ID = Orders.Customer_ID
GROUP BY C.Customer_ID
HAVING COUNT(O.Customer_ID) > @MinimumOrders

答案 1 :(得分:0)

考虑使用窗口COUNT子句。由于我没有关于您情况的所有细节,我已经包含了整个测试用例。您关心的部分是底部的SELECT

DECLARE @Cust TABLE (
    CustID INT
)

DECLARE @Ord TABLE (
    OrdID INT IDENTITY (1,1),
    CustID INT,
    Qty INT,
    Price MONEY
)

INSERT INTO @Cust 
VALUES
(1),
(2),
(3),
(4)

INSERT INTO @Ord
VALUES
(1, 5, 5.55),
(2,3,3.33),
(2,4,3.22),
(3,4,1.23),
(3,5,5.66),
(3,7,1.22)

DECLARE @MinimumOrders INT = 0

SELECT
    C.CustID,
    CASE
        WHEN COUNT(O.OrdID) OVER(PARTITION BY C.CustID) > @MinimumOrders THEN COUNT(O.OrdID) OVER(PARTITION BY C.CustID)
        ELSE NULL
    END AS Orders,
    O.Qty,
    O.Price
FROM
    @Cust C
    LEFT JOIN @Ord O
        ON C.CustID = O.CustID