2016-11-30 23 views
1

我正在努力库存管理系统我在哪里追踪产品的发布日期。所以,我的条件是 - 如果存储ID为1,今年是2014年,那么它应该返回所有的产品针对特定年份的发行日期如下:使用左连接获取所有日期

Product - Date - TotalIssued 
Keyboard - 2014-10-10 - 1 -- This product has been issued or given 1 time on that date of the year 2014 
Mouse - 2014-10-11 - 1 
Keyboard - 2014-10-12 - 0 
Mouse - 2014-10-12 - 0 
------------------------- 
------------------------- 
Keyboard - 2014-12-31 - 0 
Mouse - 2014-12-31 - 0 -- This will continue till the end of the year 

我试图使用日历表使用下面的链接,并创建一个:

Calendar Table

我用下面的查询使用日历表以获得所需的输出,但它仅返回已发出,这意味着仅存储在该日期的产品在ReturnToStore表:

SELECT l.ItemName AS Product, m.PKDate AS Date, COUNT(m.PKDate) AS TotalIssued 
FROM [days] m 
LEFT JOIN ReturnToStore k ON CONVERT(DATE, k.IssuedDate) = m.PKDate 
LEFT JOIN Item l ON l.ItemID = k.ItemID 
WHERE m.calendar_year = 2014 AND k.StoreID = 1 
GROUP BY k.StoreID, l.ItemName, m.PKDate 

现在这是我得到的输出:正如我我已经更新后:

Product - Date - TotalIssued 
Keyboard - 2014-10-10 - 1 
Mouse - 2014-10-11 - 1 

下面是表的结构:

CREATE TABLE [dbo].[Item](
     [ItemID] [int] IDENTITY(1,1) NOT NULL, 
     [ItemName] [varchar](50) NULL, 
     [Description] [varchar](150) NULL, 
     [Tag] [varchar](50) NULL, 
    CONSTRAINT [PK_Item] PRIMARY KEY CLUSTERED 
    (
     [ItemID] ASC 
    ) 
    ) ON [PRIMARY] 

    INSERT INTO [dbo].[Item] 
       ([ItemName] 
       ,[Description] 
       ,[Tag]) 
     VALUES 
       ('Keyboard', 'IT Equipment', ''), 
       ('Mouse', 'IT Equipment', '') 

    CREATE TABLE [dbo].[ReturnToStore](
     [ID] [int] IDENTITY(1,1) NOT NULL, 
     [StoreID] [int] NULL, 
     [CategoryID] [int] NULL, 
     [ItemID] [int] NULL, 
     [Quantity] [float] NULL, 
     [IssuedDate] [datetime] NULL, 
     [Description] [varchar](150) NULL, 
     [OrderID] [varchar](50) NULL, 
    CONSTRAINT [PK_ReturnToStore] PRIMARY KEY CLUSTERED 
    (
     [ID] ASC 
    ) 
    ) ON [PRIMARY] 

    INSERT INTO [dbo].[ReturnToStore] 
       ([StoreID] 
       ,[CategoryID] 
       ,[ItemID] 
       ,[Quantity] 
       ,[IssuedDate] 
       ,[Description] 
       ,[OrderID]) 
     VALUES 
       (1, 1, 1, 10, '2014-10-10 00:00:00.000', '', 'PO-02'), 
       (1, 1, 2, 20, '2014-10-11 00:00:00.000', '', 'PO-03') 

**Note:** I guess, this could be done easily with LEFT JOIN using calendar table. But got stuck here. 

编辑将查询转换为以下几点:

CREATE PROCEDURE [dbo].[MonthlyConsumption] 
@StoreID int, 
@Year int 

AS 

SELECT Distinct ItemName, 
    [1] AS M1, 
    [2] AS M2, 
    [3] AS M3, 
    [4] AS M4, 
    [5] AS M5, 
    [6] AS M6, 
    [7] AS M7, 
    [8] AS M8, 
    [9] AS M9, 
    [10] AS M10, 
    [11] AS M11, 
    [12] AS M12 
FROM 
(SELECT MONTH(m.PKDate) as YEAR, 
p.ItemName, k.IssuedDate, k.ItemID 
FROM [days] m 
CROSS JOIN (SELECT DISTINCT itemName,itemID FROM Item) p 
LEFT JOIN ReturnToStore k 
ON CONVERT(DATE, k.IssuedDate) = m.PKDate AND 
    p.itemid = k.itemid AND 
    k.StoreID = @StoreID 
LEFT JOIN Item l 
ON l.ItemID = k.ItemID 
WHERE m.calendar_year = @Year 
GROUP BY p.ItemName, m.PKDate, k.ItemID, k.IssuedDate) 

source 
PIVOT 
(
    COUNT(ItemID) 
    FOR YEAR 
    IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) 
) AS PivotDay 

返回下面的输出:

SP_Pivot

我不知道为什么它是重复的,如果我添加了同样的产品比一次在特定日期较多,那么就没有在枢轴所示变化并且它与给定的输出保持一致。

回答

1

你的第一个错误实际上是由于你的WHERE条款,而不是ON子句中放置在LEFT JOIN的右表的条件。

第二件事情,你也应该使用派生表项目名称,就像日期:

SELECT p.ItemName AS Product, m.PKDate AS Date, COUNT(l.ItemID) AS TotalIssued 
FROM [days] m 
CROSS JOIN (SELECT DISTINCT itemName,itemID FROM Item) p 
LEFT JOIN ReturnToStore k 
ON CONVERT(DATE, k.IssuedDate) = m.PKDate AND 
    p.itemid = k.itemid AND 
    k.StoreID = 1 
LEFT JOIN Item l 
ON l.ItemID = k.ItemID 
WHERE m.calendar_year = 2014 
GROUP BY p.ItemName, m.PKDate 
+0

已处理,但对于TotalIssued列,它始终显示为1的所有日期。如果当年没有在特定日期发布产品,则TotalIssued列将为0. –

+0

是的,需要对右侧表中的不同列进行计数。立即试用@ AT-2016 – sagi

+0

完美工作。非常感谢@sagi。 –

1

我不知道,如果这是解决方案,但至少这是一种进步...

LEFT JOIN,把右侧表的条件ON子句中得到真正的LEFT JOIN行为。 (当在WHERE时,你会得到经常的INNER JOIN结果。) move k.StoreID = 1ON条款:

SELECT l.ItemName AS Product, m.PKDate AS Date, COUNT(m.PKDate) AS TotalIssued 
FROM [days] m 
LEFT JOIN ReturnToStore k ON CONVERT(DATE, k.IssuedDate) = m.PKDate AND k.StoreID = 1 
LEFT JOIN Item l ON l.ItemID = k.ItemID 
WHERE m.calendar_year = 2014 
GROUP BY l.ItemName, m.PKDate 
+0

查询工作,但它没有显示为未发行的日期,产品名称对于TotalIssued列,它对所有日期显示1。 –