【问题标题】:SQL - Possible to sum rows between particular values?SQL - 可以对特定值之间的行求和吗?
【发布时间】:2018-03-27 05:58:13
【问题描述】:

如果这是重复的,我深表歉意,但我找不到我的特定问题的答案。我有一张表格,列出了销售订单上的产品及其各种数量。某些产品是其他产品的组件,并用标志表示。我想知道是否有办法为每个父/正常项目重置父/正常项目的运行总计。

这是表格数据和我想要的输出的示例:

OrderNo Item Qty Regular Line 349443 AFU20451-KIT1 1 Y 1 349443 AFU20451 0 N 2 349443 HAWKE-14252 1 N 3 349443 RGPM-25H4 1 N 4 349443 AV-003-265 1 Y 5 349443 AV-A00090-KIT 1 Y 6 349443 AV-A00091 1 N 7 349443 AV-A00090 1 N 8 349443 AV-00043 1 N 9 349443 AV457/310GR/FP 2 Y 10

想要的输出:

OrderNo Item Qty 349433 AFU20451-KIT1 3 349433 AV-003-265 1 349433 AV-A00090-KIT 4 349433 AV457/310GR/FP 2

如您所见,我想在每次显示 Y 时重置总和,仅包括父项(我可以解决这个问题,因为我可以保持项目的顺序相同,可以使用行号) .我一直在尝试使用 Over 和 Partition by 来做到这一点,但无济于事。让我知道这是否可行,或者您是否需要任何进一步的信息。

【问题讨论】:

  • 这是假设您的记录有一些顺序,但我无法通过查看您的数据来判断我将如何对它们进行排序。你是如何在你的声明中排序的?
  • 提示:分区方式
  • 您将在这里找到的问题是数据库没有内在顺序。如果没有 id 列或其他方法,您无法保证每次返回的记录顺序都相同。在您的示例中,您是否有一个 ID 字段或保持顺序的东西?
  • 是的,抱歉,我没有包含它,但是有一个列按照它们应该在的确切顺序列出了项目。组件产品始终直接位于父项目的下方。
  • 您能否在上面的数据屏幕中包括该列以保证项目的顺序如上所示。

标签: sql sql-server tsql


【解决方案1】:
with cte as 
 ( 
   select OrderNo, 
      -- only return the main item
      case when Regular = 'Y' then Item end AS Item, 
      Qty,
      -- assign a unique number to each `YNNN..` component group
      -- needed for GROUP BY in next step
      sum(case when Regular = 'Y' then 1 else 0 end)
      over (partition by OrderNo
            order by Line
            rows unbounded preceding) as grp
   from myTable
 )
select OrderNo,
   -- find the matching value for the main component
   max(Item), 
   sum(Qty)
from cte
group by OrderNo, grp

【讨论】:

  • 最初我认为这不起作用,但这只是由于我的数据发生了变化。这非常有效!非常感谢。
【解决方案2】:

目前的表现违反第一科德规则。

规则 1:信息规则:关系数据中的所有信息 base 在逻辑级别明确表示,并且恰好在一个 方式 - 按表格中的值。

但我相信您仍然可以创建 FUNCTION/PROCEDURE 并使用 Y/N 的 IF 语句逐行迭代。例如。您创建新表,如果 Y - 将新行添加到表中,如果 N - 将 +1 添加到 QTY 到最新行。

【讨论】:

    【解决方案3】:

    我会创建两个单独的表:制造商和零件,以获取值,这样您就不必手动堵塞每个库存,或者关心它们在发票列表中的位置。

    [1 []2

    然后,您需要做的就是将这些值与零件表进行比较以获取此数据。这是更多的前期工作,但将所有这些都保存和存储会有所回报。未来的示例查询如下所示:

    SELECT OrderNo.OrderTable, Item.OrderTable, Sum(Qty.OrderTable) AS Quantity
    FROM OrderTable INNER JOIN Part ON OrderTable.Item = Table.PartName
    GROUP BY OrderNo.OrderTable, Item.OrderTable, Regular.OrderTable, Part.ParentID;
    

    【讨论】:

    • 制造商表是干什么用的?您只需要零件表中的ParentID。当然你可能有嵌套部件,即部件爆炸材料清单,然后你需要递归......
    • 我只是假设如果您有一个零件表,那么您也将拥有多个要跟踪的制造商。我只是不想推荐一个零件表来查找以单词列出的制造商,而不是引用一个表。
    • 但是你也有一个OrderNo,所以必须有一个Orders 表和供应商和客户... :-)
    • 您会认为——但我不会仅从这张表中假设。我不知道订单号是为客户生成的,还是来自采购订单。制造商和供应商不一定是同一家公司。
    【解决方案4】:

    试试这个:

    select orderno, item, sum(qty) over(partition by regular order by regular)
    from your_table 
    group by  orderno, item, regular
    

    【讨论】:

    • order by regular 将简单地将它们放入 n,n,n,n,y,y,y,y 列表中,而不保留他在这里的半任意顺序。
    • 也许按 Line 订购而不是按常规订购可以解决问题。此答案后更新了问题..
    • 是的,这个答案是在他试图做的事情成为可能之前出现的。包含 line 使该解决方案可行(至少在伪理论中。不应该有 from 子句吗?)
    猜你喜欢
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 2020-08-27
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2010-12-09
    相关资源
    最近更新 更多