Sql 使用左连接获取所有日期

Sql 使用左连接获取所有日期,sql,sql-server-2008,Sql,Sql Server 2008,我正在尝试使用库存管理系统,在该系统中我必须跟踪产品的发布日期。因此,我的条件是-如果门店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 K

我正在尝试使用库存管理系统,在该系统中我必须跟踪产品的发布日期。因此,我的条件是-如果门店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
我尝试使用以下链接使用日历表,并创建了一个:

我使用以下查询使用日历表获得所需的输出,但它只返回已发布的产品,这意味着只返回存储在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.
已编辑:我已更新帖子,因为我已使用以下内容将查询转换为pivot:

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
返回以下输出:


我不知道为什么会重复,如果我在特定日期多次添加相同的产品,那么透视图中不会显示任何更改,并且与给定的输出保持不变。

我不确定这是否是解决方案,但至少这是一个改进

LEFT JOIN
时,将右侧表的条件放入
ON
子句中,以获得true
LEFT JOIN
行为。(在
WHERE
中时,您将获得常规的
内部联接
结果。)即
将k.StoreID=1移动到
ON
子句:

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

您的第一个错误是,您在
WHERE
子句中的
LEFT JOIN
的右表上放置了一个条件,而不是
on
子句

第二件事,您还应该为项目名称使用派生表,就像日期一样:

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

查询成功,但它没有显示未发布日期的产品名称,对于TotalIssuited列,它显示所有日期的1。成功,但对于TotalIssuited列,它始终显示所有日期的1。如果在该年的特定日期没有发布任何产品,则TotalIssuited列将为0。是的,需要从右表中计算不同的列。现在试试@AT-2016,效果很好。非常感谢@sagi。一切都很好@sagi,但最后一件事。我编辑了这篇文章。如果你能看到帖子,请告诉我。谢谢。@AT-2016这是一个不同的问题,你应该打开一个新的帖子。我不太擅长旋转。