【问题标题】:Pivoting a field based on date range in table B that is >= date range in table A根据表 B 中 >= 表 A 中的日期范围的日期范围透视字段
【发布时间】:2022-01-01 11:52:12
【问题描述】:

我正在尝试将一行转换为基于格式化日期“yyyy-MMM”的列,虽然这在当前月份按预期工作,但在未来几个月无法工作,我不知道如何修复非常感谢您对此的任何反馈。

这里有一点背景: 我从供应商汇总表中购买了数量,其中包含有关合同的信息,例如合同类型、数量、批号、格式为“yyyy-MMM”的创建日期,因为实际日期对于此目的并不重要。

剩余数量是来自项目分类帐条目表的另一个字段,它本质上是根据批号汇总各种条目。

Consumed Quantity 是我试图根据消耗的月份来调整的,并且也来自带有条目类型过滤器的项目分类帐条目

SELECT * 
FROM 
(
SELECT VS.[Vendor Name], VS.[Vendor No_] AS 'Vendor_No', VS.[Date] AS 'Date', 
SUM(VS.Quantity) AS 'Contracted_Quantity',
SUM(CQ.Consumed_Qty*-1) AS 'Consumed_Qty',
SUM(RQ.Remaining_Qty) AS Remaining_Qty,
'Contract Type' = 
CASE 
  WHEN VS.[Contract Type] = 1 THEN 'CONTRACT A'
  WHEN VS.[Contract Type] = 2 THEN 'CONTRACT B'
  ELSE 'OTHERS'
  END 
FROM
(SELECT [Document No_],[Vendor No_],[Lot No_],FORMAT([Date Created], 'yyyy-MMM') AS 'Date'
      ,[Purch_ Contract No_],[Contract Type],[Quantity] FROM [A].[dbo].[Company$Volume Summary]) VS

/*to identify remaining quantity by lot (Lot no. is included in my VS alias statement)*/
LEFT JOIN (SELECT [Lot No_] ,SUM([Remaining Quantity]) AS Remaining_Qty FROM [A].[dbo].[Company$Item Ledger Entry]
  GROUP BY [Lot No_]) RQ on RQ.[Lot No_] = VS.[Lot No_]

/*to identify consumed volume, if consumption is in future month compared to purchase month, it doesn't populate, this is where I believe the problem is*/
LEFT JOIN (SELECT [Lot No_],FORMAT([Posting Date], 'yyyy-MMM') AS 'Date',SUM([Quantity]) AS Consumed_Qty
FROM [A].[dbo].[Company$Item Ledger Entry]
WHERE [Entry Type] = '5' 
GROUP BY [Lot No_], Format([Posting Date], 'yyyy-MMM')) CQ on CQ.[Lot No_] = VS.[Lot No_] and CQ.Date >= VS.[Date]

GROUP BY VS.[Vendor Name], FORMAT(VS.[Date Created],'yyyy-MMM'), PT.[Contract Type], VS.[Vendor No_]
) cs 
PIVOT
(
 SUM(Consumed_Qty)
  for Date in ([2021-Sep], [2021-Oct], [2021-Nov])
  ) pvt

结果(仅显示部分):

如您所见,第二条 ABC Technology 记录显示了 2021 年 10 月的消费量,这是准确的,但是,根据也是在 2021 年 10 月购买的合同金额,以及该记录中剩余的内容,消费量需要为 9,373,与 2021 年至 10 月准确显示的 8,990 相比,短(383)。在这种情况下,2021 年 11 月的 383 实际消耗量正在下降,但是,我的代码似乎没有反映出来。

这也是 Zebra 技术记录中的确切情况,其中剩余的为 0,这意味着它已完全消耗,但是,因为它们的购买合同日期都是 2021 年至 9 月,并且消耗量是在未来的 2021 年至 10 月,SQL 脚本不会执行此操作。

如果能提供任何帮助解决此问题的指导,我将不胜感激,并提前致谢。

【问题讨论】:

  • 请提供示例数据和预期输出作为文本而不是图像。 [Lot No_] 是如何考虑的,你为什么要加入它?从您提供的信息中我们看不到任何这些。 EOMONTH(VS.[Date Created]) 可能比 FORMAT(VS.[Date Created],'yyyy-MMM') 性能更好(并且可能更准确)。
  • Lot_No 显示库存所在的位置,一旦购买了 x 数量,这就是购买的总数量分配到的位置。汇总时针对此批号的项目分类帐条目显示了我们与每个批次相关的总消耗量。问题是购买日期对我的目的无关紧要,目标是确定每月消耗了多少数量,这就是为什么我将日期格式化为 yyyy-MMM 格式并添加了一个 >= 购买日期的连接但是,除了批号之外,它不识别消耗>购买日期

标签: sql sql-server tsql pivot


【解决方案1】:

您基于 VS.[Date] 进行旋转,即购买批次的时间,而不是消费的时间。最后三列仅显示当月购买和消费的商品时的数字。

不要对整个数据集进行透视,而是将透视移到第三个子查询中。这简化了查询,首先获取包括 Contracted_Qty 和 Remaining_Qty 在内的 Lot 详细信息,然后加入第三个子查询,该子查询是三个月内按 Lot 的 Consumed_Qty 的透视集。

SELECT VS.[Vendor Name], VS.[Vendor No_] AS 'Vendor_No',
VS.[Contracted_Quantity],
RQ.Remaining_Qty AS Remaining_Quantity,
'Contract Type' = 
CASE 
  WHEN VS.[Contract Type] = 1 THEN 'CONTRACT A'
  WHEN VS.[Contract Type] = 2 THEN 'CONTRACT B'
  ELSE 'OTHERS'
  END,
CQ.[2021-Sep], CQ.[2021-Oct], CQ.[2021-Nov]

FROM
    (
    /* List of Lots with details */
    SELECT 
        [Document No_],[Vendor No_],[Lot No_], [Purch_ Contract No_],[Contract Type],[Quantity] AS [Contracted_Quantity]
    FROM [A].[dbo].[Company$Volume Summary]
    ) VS

    /* Remaining Quantity for each Lot */
    LEFT JOIN (
        SELECT [Lot No_] , SUM([Remaining Quantity]) AS Remaining_Quantity 
        FROM [A].[dbo].[Company$Item Ledger Entry]
        GROUP BY [Lot No_]
        ) RQ on RQ.[Lot No_] = VS.[Lot No_]

    /* Consumed Quantity per Lot for three months*/
    LEFT JOIN (

        SELECT [Lot No_], [2021-Sep], [2021-Oct], [2021-Nov]
        FROM 
        (
        SELECT [Lot No_], FORMAT([Posting Date], 'yyyy-MMM') AS 'Date', SUM([Quantity]) AS Consumed_Qty
        FROM [A].[dbo].[Company$Item Ledger Entry]
        WHERE [Entry Type] = '5' 
        GROUP BY [Lot No_], Format([Posting Date], 'yyyy-MMM')
        ) AS src
        PIVOT
        (
         SUM(Consumed_Qty)
          for [Date] in ([2021-Sep], [2021-Oct], [2021-Nov])
          ) pvt

        ) CQ on CQ.[Lot No_] = VS.[Lot No_]
;

没有数据我无法测试这个查询,但它应该非常接近。

【讨论】:

  • 感谢您的回复。我之所以使用 SUM(remaining) 是因为项目分类帐条目表有多种条目类型,采购、调整、消耗。每个批号的所有条目类型的总和是让我获得剩余数量的原因,它确实与我的批次库存分类帐相关联。但是,当我现在在数据透视表中使用 CQ.Date 并删除 CQ 上的 >= 日期连接时,它现在会复制每个月消费的购买记录,从而导致现在按批次购买的总数不正确。我可以提供哪些其他数据来帮助更好地解释我的问题?非常感谢您的时间和帮助
  • 下一个调整是将枢轴移动到第三个子查询中。无需旋转整个数据集,而是获取包括 Contracted_Qty 和 Remaining_Qty 在内的 Lot 详细信息,然后加入第三个子查询,即三个月内按 Lot 的 Consumed_Qty 的旋转集。
  • 我仍然很好奇如何通过对某个数字求和来获得剩余数量。你能提供一些示例数据来演示吗?
  • 不要介意剩余的数量。我刚刚意识到您的分类帐表必须将每个数字记录在两列中。剩余数量是正数或负数,具体取决于条目类型。将其相加将得出剩余数量。列名让我失望。
  • 是的,这是正确的!这就是分类帐表记录每个条目的方式。
猜你喜欢
  • 1970-01-01
  • 2013-12-02
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 2012-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多