在SQL中,尝试链接2个表,仅为当前月添加缺失行

时间:2016-10-21 19:47:55

标签: sql-server tsql sql-server-2012

我正在尝试从下表和视图中将数据插入到表中。 该脚本将在该月的最后一天运行,并将此信息插入到SqFtByMonth中。我相信它与我的WHERE子句有关。 WarehouseBaseSqFt中有6个仓库,而且并非所有仓库每月都在StorageUsageCones中。我正在尝试构建一个表,在月末运行脚本时,每个月为每个仓库提供一行。使用我当前的代码,我只在StorageUsageConesMonthly View中为每个仓库接收一行。

TABLE [dbo].[WarehouseBaseSqFt](
[Warehouse] [varchar](10) NOT NULL,
[WarehouseName] [varchar](50) NOT NULL,
[TotalSqFt] [int] NOT NULL,
[UsableSqFt] [int] NOT NULL,
[GLDept] [int] NULL

VIEW [dbo].[StorageUsageConesMonthly] AS
SELECT TOP 1000 [COUNTYEAR]
  ,[COUNTMONTH]
  ,[IDWHSE]
  ,[GLDept]
  ,[IDLOCATION]
  ,[IDCUST]
  ,[PltQtyPerMonth]
  ,[DaysOccupied]
  ,[DaysInMonth]
  ,CAST(PltQtyPerMonth /DaysInMonth * 17.33333 / 2 AS decimal (8,4))AS SqFtUtilized


INSERT INTO [dbo].[SqFtByMonth] ([Warehouse],[CountYear],[CountMonth],[TotalSqFt],[BaseUsableSqFt] ,[ConeSqFt] ,[UsableSqFtForMonth])
SELECT  CASE WHEN sucm.IDWHSE IS NULL THEN wbs.Warehouse
            ELSE sucm.IDWHSE
    END AS  Warehsoue,
    YEAR(SYSDATETIME()),
    MONTH(SYSDATETIME())-1,
    wbs.TotalSqFt,
    wbs.UsableSqFt,
    CASE WHEN SUM(sucm.SqFtUtilized) is null THEN 0
            ELSE SUM(sucm.SqFtUtilized)
    END AS ConeSqFt,
    CASE WHEN SUM(sucm.SqFtUtilized) is null THEN wbs.UsableSqFt
            ELSE wbs.UsableSqFt + SUM(sucm.SqFtUtilized) 
    END AS UsableSqFtForMonth 
FROM [dbo].[StorageUsageConesMonthly] sucm

full outer JOIN [dbo].[WarehouseBaseSqFt] wbs
ON wbs.Warehouse = sucm.IDWHSE
  WHERE sucm.COUNTYEAR = YEAR(SYSDATETIME()) AND sucm.COUNTMONTH =  MONTH(SYSDATETIME())
GROUP BY sucm.COUNTYEAR,
    sucm.COUNTMONTH,
    sucm.IDWHSE,
    wbs.Warehouse,
    wbs.TotalSqFt,
    wbs.UsableSqFt


    ORDER BY Warehouse

感谢您的帮助, 格里

1 个答案:

答案 0 :(得分:1)

是的,您的WHERE子句是导致问题的原因。对于没有StorageUsageConesMonthly记录的仓库,sucm.COUNTYEARsucm.COUNTMONTH也是NULL。在WHERE子句中使用它们时,它们与当前年份和月份不匹配,并且输出中不存在这些仓库。

我猜你只想在这个月发布这些数据。然后CTE可能会帮助

WITH CTE AS 
(
    SELECT *
    FROM [dbo].[StorageUsageConesMonthly] sucm
    WHERE sucm.COUNTYEAR = YEAR(SYSDATETIME()) AND sucm.COUNTMONTH =  MONTH(SYSDATETIME())
)
INSERT INTO [dbo].[SqFtByMonth] ([Warehouse],[CountYear],[CountMonth],[TotalSqFt],[BaseUsableSqFt] ,[ConeSqFt] ,[UsableSqFtForMonth])
SELECT  CASE WHEN CTE.IDWHSE IS NULL THEN wbs.Warehouse
        ELSE CTE.IDWHSE
END AS  Warehsoue,
        YEAR(SYSDATETIME()),
        MONTH(SYSDATETIME())-1,
        wbs.TotalSqFt,
        wbs.UsableSqFt,
        CASE WHEN SUM(CTE.SqFtUtilized) is null THEN 0
                ELSE SUM(CTE.SqFtUtilized)
        END AS ConeSqFt,
        CASE WHEN SUM(CTE.SqFtUtilized) is null THEN wbs.UsableSqFt
                ELSE wbs.UsableSqFt + SUM(CTE.SqFtUtilized) 
        END AS UsableSqFtForMonth 
FROM CTE full outer JOIN [dbo].[WarehouseBaseSqFt] wbs
        ON wbs.Warehouse = CTE.IDWHSE    
GROUP BY CTE.COUNTYEAR,
         CTE.COUNTMONTH,
         CTE.IDWHSE,
         wbs.Warehouse,
         wbs.TotalSqFt,
         wbs.UsableSqFt

这可能不是你想要的,但我想这足以证明这个想法。请勿使用WHERE中的FULL OUTER JOIN进行过滤。而是首先单独过滤表,然后进行连接。

此外,您不需要使用CTE,将CTE查询作为嵌套查询放在FROM子句中,可以获得相同的结果。