【问题标题】:Grouping by row number in a column按列中的行号分组
【发布时间】:2015-10-15 19:24:05
【问题描述】:

假设您在数据库中有这组记录:

PartNumber     Qty    Group  
   A           1       1   
   B           2       1
   C           3       1
   B           4       1
   a           1       2
   B           2       2
   C           3       2
   B           4       2

我们怎样才能得出这个结果:

   A       2
   B       4
   C       6
   B       8

即第一组第一行与第二组第一行、第一组第二行与第二组第二行、第一组第三行与第三行相加第二组,以此类推。

注意事项:
*- 我可以有多个组
*- 组将始终具有相同的长度(即每个组的行数相同)
*- 组中的零件编号将始终按相同顺序相同
*- 我可以重复多个零件号,即不仅 B 重复,而且每个组都重复

我知道我可以在表格中添加一个新列来获得类似这样的内容:

PartNumber    Qty    Group    idx
   A          1       1       1
   B          2       1       2
   C          3       1       3
   B          4       1       4
   a          1       2       1
   B          2       2       2
   C          3       2       3
   B          4       2       4

and: select partnumber, sum(qty) from table group by idx
但这正是我做不到的。有什么建议么?

【问题讨论】:

  • 你用的是什么版本的sql-server?
  • @JNevill "Microsoft SQL Server 2008 R2 (SP3) "
  • 您的表只是一组无序的(PartNumber, Qty, Group 值。因此,每组没有第一行、第二行等。您的表格中是否还有另一列管理顺序?
  • @GiorgosBetsos 是的,我有一个 Id(自动增量)列。很抱歉之前没有提到。
  • 您的最后 4 行样本 idx = 1 - 1 - 3 - 4 ?可以吗?

标签: sql sql-server database


【解决方案1】:

您可以使用ROW_NUMBER 来创建您在OP 中提到的idx 字段。然后它是一个简单的GROUP BY 以获得所需的结果:

SELECT PartNumber, SUM(Qty)
FROM (
   SELECT PartNumber, Qty, 
          ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY id) AS idx
   FROM mytable) AS t
GROUP BY PartNumber, idx
ORDER BY idx

分组依赖于 OP 中所述的这条规则:

组中的零件编号将始终相同,顺序相同

我相信上述规则(第 3 条)构成了第 3 条规则。 2个冗余。

【讨论】:

    【解决方案2】:

    SQL 表代表无序 集合。让我假设有另一个列指定了排序(qty 看起来像这样一个列,但它似乎有另一个目的)。

    有了这个列,我们可以使用row_number(),假设你的条件是真的,这就变成了一个简单的聚合查询:

    select min(PartNumber) as PartNumber, sum(qty) as qty
    from (select t.*, row_number() over (partition by group order by id) as seqnum
          from t
         ) t
    group by seqnum;
    

    不过,我更喜欢这个版本,只是为了检查部件号:

    select (case when min(PartNumber) = max(PartNumber) then min(PartNumber)
                 else 'Oops! Parts don''t match'
            end) as PartNumber, sum(qty) as qty
    from (select t.*, row_number() over (partition by group order by id) as seqnum
          from t
         ) t
    group by seqnum;
    

    【讨论】:

      【解决方案3】:

      这似乎工作正常:-

      with temptable as
      (
      select 
          [PartNumber], 
          [Qty], 
          ROW_NUMBER() over(partition by [group] order by [group]) [idx]
      from #temp
      )
      
      select PartNumber, SUM(Qty)
      from temptable
      group by Partnumber, [idx]
      

      见小提琴http://sqlfiddle.com/#!3/cfa38/1

      【讨论】:

        猜你喜欢
        • 2019-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-26
        • 2019-01-13
        • 2013-11-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多