Sql查询以按客户类型获取总订单(计数)

时间:2013-10-25 09:11:19

标签: sql-server

我有2个表“订单”和“客户”。

我想根据每个月,每周和每个客户类型计算订单数量。

订单表有orderid和CustomerIDfields。

Customers表具有CustomerID和CustomerTypeID字段。

我试过以下查询: -

SELECT 
                "Month" = month(o.OrderDate)
                 , "Year" = year(o.OrderDate)
                 , NoOfCustomer = Count(o.Total)                     
            FROM
                Orders o        
              INNER JOIN 
              Customers C on C.CustomerID = o.CustomerID                          
            WHERE
                o.OrderDate >= convert(DATETIME, '1/1/2013 12:00:00 AM')
                AND o.OrderDate < convert(DATETIME, '12/31/2013 12:00:00 AM')
            GROUP BY
                month(o.OrderDate)
              , year(o.OrderDate)

            ORDER BY
                year(o.OrderDate)
              , month(o.OrderDate)

我想要的结果如下: -

Month   Year  NoOfCustomer CustomerType
1       2013    45625         1
2       2013    12131         2
3       2013    54544         3
4       2013    7888          4
1       2013    5652          1
2       2013    5655          2
3       2013    5522          3
4       2013    555           4

提前致谢。

3 个答案:

答案 0 :(得分:2)

试试这个:

SELECT MONTH(o.OrderDate) as MonthValue, 
       YEAR(o.OrderDate) as YearValue, 
       C.CustomerType, Count(o.Total) as NoOfOrders
FROM Orders o        
INNER JOIN Customers C on C.CustomerID = o.CustomerID                          
WHERE o.OrderDate >= CONVERT(DATETIME, '1/1/2013 00:00:00 AM')
AND o.OrderDate <= CONVERT(DATETIME, '12/31/2013 23:59:59 PM')
GROUP BY MONTH(o.OrderDate), 
         YEAR(o.OrderDate), 
         C.CustomerType 
ORDER BY MONTH(o.OrderDate),
         YEAR(o.OrderDate)

<强>更新

如果您想为每个客户类型获取每个月的结果,那么您需要添加UNION,如下所示:

; with CTE AS
(
       SELECT MONTH(CAST('01/01/2013' AS DateTime)) [Month], 2013 [Year], CustomerType, 0 NoOfCustomers 
       FROM Customers
       UNION ALL 
       SELECT [MONTH] + 1, 2013 [Year], CustomerType, 0 NoOfCustomers  
       FROM CTE 
       WHERE [Month] <= 12 
       AND CustomerType NOT IN 
       (
           SELECT C.CustomerType 
           FROM [Orders] O INNER JOIN Customers C ON C.CustomerID = o.CustomerID    
           WHERE MONTH(O.OrderDate) = CTE.[Month] AND YEAR(O.OrderDate) = 2013
       )
  )

SELECT * FROM
 (
    SELECT DISTINCT  [Month], [Year], CustomerType, NoOfCustomers  FROM CTE
    UNION
    SELECT MONTH(o.OrderDate) as [Month], 
           2013 as [Year], 
           C.CustomerType, 
           COUNT(o.Total) as NoOfCustomers
    FROM [Orders] o        
    INNER JOIN Customers C on C.CustomerID = o.CustomerID
    WHERE YEAR(o.OrderDate) = 2013
    GROUP BY MONTH(o.OrderDate), C.CustomerType 
    ) tt
 ORDER BY [Month], [Year], CustomerType

答案 1 :(得分:0)

也许这会有所帮助

    DECLARE @DateStart DATETIME, @DateEnd DATETIME;
    SET @DateStart = CONVERT(DATETIME, '1/1/2013 12:00:00 AM');
    SET @DateEnd = CONVERT(DATETIME, '12/31/2013 12:00:00 AM');

    SELECT 
    MONTH(o.OrderDate) [Month]
    , YEAR(o.OrderDate) [Year]
    , ISNULL(C.CustomerType,0) [CustomerType]
    , COUNT(o.Total) [NoOfCustomer]                  
    FROM Orders o        
    LEFT OUTER JOIN Customers C on C.CustomerID = o.CustomerID                          
    WHERE o.OrderDate BETWEEN  @DateStart AND @DateEnd
    GROUP BY MONTH(o.OrderDate), YEAR(o.OrderDate), ISNULL(C.CustomerType,0)
    ORDER BY [Year],[Month],[CustomerType];

更新

    DECLARE @DateStart DATETIME, @DateEnd DATETIME;
    DECLARE @CustTypeTable TABLE(CustomerType INT);
    DECLARE @i INT = 0;
    /*Create table variable for customer types*/
    WHILE @i < 5
    BEGIN
        INSERT INTO @CustTypeTable
        SELECT @i
        SET @i = @i + 1
    END

    /*The statement will force all CustomerTypes with a "fake" table*/
    DECLARE @StagingTable TABLE([Month] INT, [Year] INT, CustomerType INT)
    INSERT INTO @StagingTable
    SELECT 
    MONTH(o.OrderDate) [Month]
    , YEAR(o.OrderDate) [Year]
    , T.CustomerType
    FROM Orders o  
    CROSS JOIN @CustTypeTable T
    GROUP BY MONTH(o.OrderDate), YEAR(o.OrderDate), T.CustomerType


    SET @DateStart = CONVERT(DATETIME, '1/1/2013 12:00:00 AM');
    SET @DateEnd = CONVERT(DATETIME, '12/31/2013 12:00:00 AM');

    /*Create another staging table for results*/
    DECLARE @StagingTable2 TABLE([Month] INT, [Year] INT, CustomerType INT, [NoOfCustomer] BIGINT)
    INSERT INTO @StagingTable2
    SELECT 
    MONTH(o.OrderDate) [Month]
    , YEAR(o.OrderDate) [Year]
    , C.CustomerType [CustomerType]
    , COUNT(o.Total) [NoOfCustomer]                  
    FROM Orders o        
    LEFT OUTER JOIN Customers C on C.CustomerID = o.CustomerID                          
    WHERE o.OrderDate BETWEEN  @DateStart AND @DateEnd
    GROUP BY MONTH(o.OrderDate), YEAR(o.OrderDate), C.CustomerType
    ORDER BY [Year],[Month],[CustomerType];

    /*Now lets join them up*/
    SELECT 
     T1.Year
    , T1.Month
    , T1.CustomerType
    , T2.[NoOfCustomer]
    FROM @StagingTable T1
    LEFT OUTER JOIN @StagingTable2 T2 ON T2.Year = T1.Year AND T2.Month = T1.Month AND T2.CustomerType =  T1.CustomerType

就像我能为你做的一样多

答案 2 :(得分:0)

我找到了解决方案,谢谢大家的帮助和时间: -

SELECT  2013 as [Year],
        months.number,
        Amount = SUM(COALESCE(o.Total,0)),
        C.CustomerTypeID
FROM    Customers C
CROSS JOIN
(SELECT number FROM master..spt_values WHERE type='p' and number between 1 and 12) months
LEFT JOIN [Orders] o on C.CustomerId = o.CustomerId and YEAR(o.OrderDate) = 2013 and MONTH(o.OrderDate) = months.number
GROUP BY months.number, C.CustomerTypeID 
ORDER BY months.number, C.CustomerTypeID