SQL Server,将表与填充空值组合在一起

时间:2018-06-15 22:32:42

标签: sql sql-server

我有三个表:CustomerSalesDetail

  • 客户表格列:CustomerIDCustomerName
  • 销售表格列:DateInvoiceCustomerID
  • 明细表格列:InvoiceItemIDQuantity

Customer表值:

CustomerID | CustomerName
-----------+--------------
     1     |    Mike
     2     |    Kavin

Sales表值:

Date     | Invoice | CustomerID
---------+---------+------------
2/3/2017 | 111111  |    1
5/2/2017 | 444444  |    2
6/1/2017 | 123456  |    1
6/5/2017 | 555555  |    1
1/4/2018 | 777777  |    2

Detail表值:

Invoice | ItemID | Quantity
--------+--------+-----------
111111  | 4      | 3
444444  | 12     | 4
123456  | 7      | 2
555555  | 7      | 5
777777  | 12     | 7

我希望仅在{1}} 7和12之间看到ItemID在4/1/2017~1 / 30/2018之间

结果应该是:

Date

我尝试了许多不同的方法,但都失败了。

CustomerID | CustomerName | Year | Month | ItemID | Quantity
-----------+--------------+------+-------+--------+-----------
    1      |       Mike   | 2017 | 4     | 7      | 0
    1      |       Mike   | 2017 | 5     | 7      | 0
    1      |       Mike   | 2017 | 6     | 7      | 7
    1      |       Mike   | 2017 | 7     | 7      | 0
    1      |       Mike   | 2017 | 8     | 7      | 0
    1      |       Mike   | 2017 | 9     | 7      | 0
    1      |       Mike   | 2017 | 10    | 7      | 0
    1      |       Mike   | 2017 | 11    | 7      | 0
    1      |       Mike   | 2017 | 12    | 7      | 0
    1      |       Mike   | 2018 | 1     | 7      | 0
    2      |       Kavin  | 2017 | 4     | 12     | 0
    2      |       Kavin  | 2017 | 5     | 12     | 4
    2      |       Kavin  | 2017 | 6     | 12     | 0
    2      |       Kavin  | 2017 | 7     | 12     | 0
    2      |       Kavin  | 2017 | 8     | 12     | 0
    2      |       Kavin  | 2017 | 9     | 12     | 0
    2      |       Kavin  | 2017 | 10    | 12     | 0
    2      |       Kavin  | 2017 | 11    | 12     | 0
    2      |       Kavin  | 2017 | 12    | 12     | 0
    2      |       Kavin  | 2018 | 1     | 12     | 7

我的代码不起作用。请帮帮我。

2 个答案:

答案 0 :(得分:1)

你所需要的是一个递归的CTE,从2017年4月1日到1月30日,逐个月份(如月份柜台)查看记录。然后,根据需要调整输出。

以下是您的需求:

DECLARE 
    @Customer TABLE (
        CustomerID      INT,
        CustomerName    VARCHAR(100)
    )
DECLARE
    @Sales  TABLE(
        [Date]      DATE, 
        Invoice     INT,
        CustomerID  INT
    )
DECLARE 
    @Detail TABLE(
        Invoice     INT,
        ItemID      INT,
        Quantity    INT  
    )
INSERT INTO @Customer VALUES 
(1,'Mike'),
(2,'Kavin')

INSERT INTO @Sales VALUES
('2/3/2017' , 111111  ,    1),
('5/2/2017' , 444444  ,    2),
('6/1/2017' , 123456  ,    1),
('6/5/2017' , 555555  ,    1),
('1/4/2018' , 777777  ,    2)

INSERT INTO @Detail VALUES 
(111111  , 4      , 3),
(444444  , 12     , 4),
(123456  , 7      , 2),
(555555  , 7      , 5),
(777777  , 12     , 7)



DECLARE 
    @StartDate          DATE =  '4/1/2017',
    @EndDate            DATE =  '8/01/2017'

;WITH CTE AS (
SELECT 
    c.CustomerID, 
    c.CustomerName,
    YEAR(s.[Date]) AS [Year],
    MONTH(s.[Date]) AS [Month],
    d.ItemID, 
    d.Quantity, 
    DATEADD(MONTH, 0, @StartDate) AS x
FROM @Sales s
LEFT JOIN @Detail d ON s.Invoice = d.Invoice
LEFT JOIN @Customer c ON c.CustomerID = s.CustomerID
    UNION ALL 
    SELECT 
      CustomerID,
      CustomerName,
      [Year], 
      [Month], 
      ItemID,
      Quantity,
    DATEADD(MONTH, 1, x) 
    FROM CTE
    WHERE  
    DATEADD(MONTH, 1, x) < @EndDate
)
    SELECT 
        CustomerID, 
        CustomerName, 
        YEAR(x) AS [YEAR], 
        MONTH(x) AS [Month],
        ItemID,
        CASE WHEN YEAR(x) = [YEAR] AND MONTH(x) = [Month] THEN SUM(Quantity) ELSE 0 END AS Quantity
    FROM CTE
    WHERE 
        ItemID IN(7,12) 
        GROUP BY 
        CustomerID, 
        CustomerName, 
        [YEAR], 
        [Month],
        ItemID, 
        x
    ORDER BY CustomerID

答案 1 :(得分:0)

因为您正在使用聚合函数(SUM),所以需要GROUP BY:

SELECT  CustomerID ,
        CustomerName ,
        YEAR([Date]) ,
        MONTH([Date]) ,
        ItemID ,
        SUM(Quantity)
FROM    Detail
        INNER JOIN Sales ON Detail.Invoice = Sales.Invoice
        INNER JOIN Customer ON Sales.CustomerID = Customer.CustomerID
WHERE   ItemID IN ( 1, 7 )
        AND [Date] > '4/1/2017'
        AND [Date] < '1/30/2018'
GROUP BYCustomerID ,
        CustomerName ,
        YEAR([Date]) ,
        MONTH([Date]) ,
        ItemID ;