分组连续行

时间:2019-02-01 11:39:59

标签: sql sql-server

在sql中对连续的行(CustomerPartNum,RevisionNum)进行分组

提供以下示例表

declare @t table (CustomerPartNum varchar(10), RevisionNum varchar(10), FileName varchar(500))

insert into @t 
values ('C1', 'A', 'a.pdf'), ('C1', 'A', 'b.pfd'), ('C1', 'A', 'c.pdf'),
       ('C2', 'X', 'p.pdf'), ('C2', 'X', 'q.pfd'),
       ('C2', 'X', 'r.pdf'), ('C2', 'X', 'y.pdf'),
       ('C1', 'A', 'a.pdf'), ('C1', 'A', 'b.pfd'), ('C1', 'A', 'd.pdf')

样本数据:

CustomerPartNum   RevisionNum   FileName
---------------------------------------------------------
C1                 A            a.pdf,b.pdf,c.pdf
C2                 X            p.pdf,q.pdf,r.pdf,y.pdf
C1                 A            a.pdf,b.pdf,d.pdf

我想用CustomerPartNum,RevisionNum对连续的行进行分组。

您可以看到表数据,将CustomerPartNum'C1'插入了3次。我想将这三个部分记录与CustomerPartNum,RevisionNum和Filename列数据进行逗号分隔。

在“ C1”之后,插入了“ C2”,我再次想将记录与CustomerPartNum,RevisionNum和“文件名”列数据进行逗号分隔。

再次插入“ C1”,这些部分应位于不同的行,如输出所示。

2 个答案:

答案 0 :(得分:1)

这是一个团体和岛屿的问题。但是,您需要一列来指定行的顺序。 SQL表显示无序集,而排序仅由数据值提供。

尽管FF..F.... ====================================================================== FAIL: test_arithmetic_1_seed (__main__.Tests) ---------------------------------------------------------------------- Traceback (most recent call last): File "tests.py", line 99, in test_arithmetic_1_seed self.assertEqual(m, "-0.008264393546") AssertionError: '0.001101632486' != '-0.008264393546' ====================================================================== FAIL: test_arithmetic_2_seeds (__main__.Tests) ---------------------------------------------------------------------- Traceback (most recent call last): File "tests.py", line 109, in test_arithmetic_2_seeds self.assertEqual(m, "0.000620653736") AssertionError: '0.000620655250' != '0.000620653736' ====================================================================== FAIL: test_random_number_1_seed (__main__.Tests) ---------------------------------------------------------------------- Traceback (most recent call last): File "tests.py", line 89, in test_random_number_1_seed self.assertEqual(num_str, "1.511062622070") AssertionError: '-1.398459434509' != '1.511062622070' ---------------------------------------------------------------------- Ran 9 tests in 0.015s 似乎有顺序,但我认为您应该明确地介绍一下:

filename

然后分配分组:

declare @t table (
    id int identity(1, 1),
    CustomerPartNum VARCHAR(10),
    RevisionNum VARCHAR(10),
    FileName varchar(500)
);

insert into @t (CustomerPartNum, RevisionNum, FileName)
    values ('C1', 'A', 'a.pdf'), . . .;

然后在最新版本的SQL Server中,可以使用 select t.*, (row_number() over (order by id) - row_number() over (partition by customerpartnum order by id) ) as grp from t )

string_agg()

在旧版本中,您可以使用适当的XML表达式替换with t as ( select t.*, (row_number() over (order by id) - row_number() over (partition by customerpartnum, RevisionNum order by id) ) as grp from t ) t select customerpartnum, RevisionNum, string_agg(filename) as filenames from t group by customerpartnum, RevisionNum, grp;

答案 1 :(得分:0)

您的语法看起来像您正在使用SQL Server,所以,我会这样做:

WITH CTE AS(
     SELECT t.*,
            pk - 
            ROW_NUMBER() OVER (PARTITION BY CustomerPartNum, RevisionNum ORDER BY pk) AS Grp
     FROM @t AS t
)

SELECT DISTINCT CustomerPartNum, RevisionNum , STUFF(FileNames, 1, 1, '') AS FileNames
FROM CTE t CROSS APPLY
     (SELECT ', '+FileName 
      FROM CTE 
      WHERE t.CustomerPartNum = CustomerPartNum AND t.RevisionNum = RevisionNum AND t.Grp = Grp
      FOR XML PATH('')
     ) TT (FileNames);

pk假定标识列指定列的顺序。