如果当月没有订单,则该月将没有行

时间:2015-02-19 18:35:18

标签: sql-server

我正在接受SQL Server培训并完成了这项任务:

  

按月显示1997年每位员工的销售量。结果应包含108条记录(9 * 12)。只有一个查询

我正在使用Northwind示例数据库。

我的查询:

Select      
     dbo.Employees.EmployeeID
    , dbo.Employees.FirstName
    , dbo.Employees.LastName
    , MONTH(OrderDate) as [Month]
    --, YEAR(OrderDate) as [Year]
    , sum([Order Details].Quantity*[Order Details].UnitPrice) as [Sales Volume]
from 
   Orders
Inner join 
   dbo.[Order Details] on dbo.[Order Details].OrderID = dbo.Orders.OrderID
Inner join 
   dbo.Employees on dbo.Employees.EmployeeID = dbo.Orders.EmployeeID
where 
   DATEPART(year, OrderDate) = 1997
group by 
   Month(OrderDate), 
   dbo.Employees.EmployeeID, dbo.Employees.FirstName, 
   dbo.Employees.LastName
order by 
   dbo.Employees.EmployeeID;

不幸的是,我只获得了104条记录,因为它们是几个月,当时员工没有任何订单(例如我想将其设置为0)。

我知道,我需要一个日历表或特殊的子查询。但我无法解决它(大约2天)。

我发现了类似的内容,但我无法将此代码块添加到我的解决方案中。

Select 
   DATEADD(MONTH, n, DATEADD(MONTH, DATEDIFF(MONTH, 0, '1997-01-01'), 0)) StartDate,
   DATEADD(MONTH, n+1, DATEADD(MONTH, DATEDIFF(MONTH, 0, '1997-01-01'), 0)) EndDate
FROM 
   (SELECT TOP 12
       (ROW_NUMBER() OVER (ORDER BY CustomerID) - 1) as n
    FROM Orders) as n 
是的,有人能帮帮我吗?

3 个答案:

答案 0 :(得分:1)

此处有查询,需要SQL Server 2008或更高版本:

WITH Months AS
(
    SELECT *
    FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) AS M(MonthNumber)
)
, EmployeesMonths AS
(
    SELECT
        E.EmployeeID, E.FirstName, E.LastName, Months.MonthNumber
    FROM
        dbo.Employees E
        CROSS JOIN Months
)
, SalesSummary AS
(
    SELECT
        O.EmployeeID,
        MONTH(O.OrderDate) AS MonthNumber,
        SUM(OD.UnitPrice * OD.Quantity * (1 - OD.Discount)) AS Sales
    FROM
        dbo.Orders O
        INNER JOIN dbo.[Order Details] OD
            ON O.OrderID = OD.OrderID
    WHERE
        YEAR(O.OrderDate) = 1997
    GROUP BY
        O.EmployeeID, MONTH(O.OrderDate)

)
SELECT
    EM.EmployeeID, EM.FirstName, EM.LastName, EM.MonthNumber,
    CAST(ISNULL(SS.Sales, 0) AS decimal(18,2)) AS Sales
FROM
    EmployeesMonths EM
    LEFT OUTER JOIN SalesSummary SS
        ON EM.EmployeeID = SS.EmployeeID AND EM.MonthNumber = SS.MonthNumber
ORDER BY
    EM.EmployeeID, EM.MonthNumber

编辑: 以上查询使用链式CTE(Common Table Expresions)。链式CTE允许您逐步处理您的问题,您不需要立即考虑整个问题。首先,我们需要数月,然后我们需要员工和月份的笛卡尔积。还需要按月和员工的销售摘要。最后,我们在最后一次查询时将所有内容粘合在一起。

答案 1 :(得分:0)

尝试以下内容:

DECLARE @o TABLE
    (
      orderid INT ,
      empid INT ,
      orderdate DATETIME ,
      amount MONEY
    )
DECLARE @e TABLE
    (
      empid INT ,
      name NVARCHAR(MAX)
    )


INSERT  INTO @e
VALUES  ( 1, 'Bob' ),
        ( 2, 'Peter' ),
        ( 3, 'Charley' )
INSERT  INTO @o
VALUES  ( 1, 1, '20140101', 100 ),
        ( 1, 1, '20150101', 1 ),
        ( 2, 1, '20150102', 2 ),
        ( 3, 1, '20150201', 2.5 ),
        ( 4, 2, '20150101', 4 ),
        ( 5, 2, '20150103', 20 ),
        ( 6, 2, '20150104', 1 )


SELECT  m.id ,
        e.empid ,
        e.name ,
        ISNULL(SUM(o.amount), 0) AS summ
FROM    ( VALUES ( 1), ( 2), ( 3), ( 4), ( 5), ( 6), ( 7), ( 8), ( 9), ( 10),
        ( 11), ( 12) ) AS m ( id )
        CROSS JOIN @e e 
        LEFT JOIN @o o ON m.id = MONTH(o.orderdate) AND e.empid = o.empid
WHERE DATEPART(year, OrderDate) = 2015 OR o.orderid IS NULL
GROUP BY m.id ,
        e.empid ,
        e.name
        ORDER BY e.empid, m.id

输出:

id  empid   name    summ
1   1       Bob     3.00
2   1       Bob     2.50
3   1       Bob     0.00
4   1       Bob     0.00
5   1       Bob     0.00
6   1       Bob     0.00
7   1       Bob     0.00
8   1       Bob     0.00
9   1       Bob     0.00
10  1       Bob     0.00
11  1       Bob     0.00
12  1       Bob     0.00
1   2       Peter   25.00
2   2       Peter   0.00
3   2       Peter   0.00
4   2       Peter   0.00
5   2       Peter   0.00
6   2       Peter   0.00
7   2       Peter   0.00
8   2       Peter   0.00
9   2       Peter   0.00
10  2       Peter   0.00
11  2       Peter   0.00
12  2       Peter   0.00
1   3       Charley 0.00
2   3       Charley 0.00
3   3       Charley 0.00
4   3       Charley 0.00
5   3       Charley 0.00
6   3       Charley 0.00
7   3       Charley 0.00
8   3       Charley 0.00
9   3       Charley 0.00
10  3       Charley 0.00
11  3       Charley 0.00
12  3       Charley 0.00

答案 2 :(得分:0)

Select      
     dbo.Employees.EmployeeID
    , dbo.Employees.FirstName
    , dbo.Employees.LastName
    , [Month].[Month]
    --, YEAR(OrderDate) as [Year]
    , sum([Order Details].Quantity*[Order Details].UnitPrice) as [Sales Volume]
from dbo.Employees
CROSS JOIN (
            SELECT 1 [month]
    UNION   SELECT 2
    UNION   SELECT 3
    UNION   SELECT 4
    UNION   SELECT 5
    UNION   SELECT 6
    UNION   SELECT 7
    UNION   SELECT 8
    UNION   SELECT 9
    UNION   SELECT 10
    UNION   SELECT 11
    UNION   SELECT 12
) [month]
LEFT JOIN Orders on dbo.Employees.EmployeeID = dbo.Orders.EmployeeID AND [month].[month]=Month(OrderDate)
LEFT join dbo.[Order Details] on dbo.[Order Details].OrderID = dbo.Orders.OrderID
where DATEPART(year, OrderDate) = 1997
group by [Month].[Month], dbo.Employees.EmployeeID, dbo.Employees.FirstName, dbo.Employees.LastName
order by dbo.Employees.EmployeeID;
相关问题