0

我需要根据 Id 对不同组进行 SUM 的行的排列和组合: 作为 SQL QUERY

CREATE TABLE TestTable2([Id] [int] NULL, [Group] [varchar](50) NULL, [PeriodStart] [varchar](50) NULL) ON [PRIMARY]

INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group1', 'date1a')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group1', 'date1b')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group1', 'date1c')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group2', 'date2a')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group2', 'date2b')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group3', 'date3a')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group3', 'date3b')<br/>
INSERT INTO TestTable2([Id], [Group], [PeriodStart]) VALUES (1, 'Group3', 'date3c')<br/>

表中数据:

**Id -- Group -- PeriodStart**<br/>
1 -- Group1 -- date1a<br/>
1 -- Group1 -- date1b<br/>
1 -- Group1 -- date1c<br/>
1 -- Group2 -- date2a<br/>
1 -- Group2 -- date2b<br/>
1 -- Group3 -- date3a<br/>
1 -- Group3 -- date3b<br/>
1 -- Group3 -- date3c<br/>

注意:可以有任意数量的组,PeriodStart 是 DateTime

输出要求为:应该是来自 3*2*3 不同组行的 18 个组合(即此处为 Group1、Group2 和 Group3),其 MAX DATE 为 PeriodStart:

**Id -- MaximumPeriodStartDate**<br/>
1 -- MAX OF (date1a, date2a, date3a)<br/>
1 -- MAX OF (date1a, date2b, date3a)<br/>
1 -- MAX OF (date1a, date2a, date3b)<br/>
1 -- MAX OF (date1a, date2b, date3b)<br/>
1 -- MAX OF (date1a, date2a, date3c)<br/>
1 -- MAX OF (date1a, date2b, date3c)<br/>

1 -- MAX OF (date1b, date2a, date3a)<br/>
1 -- MAX OF (date1b, date2b, date3a)<br/>
1 -- MAX OF (date1b, date2a, date3b)<br/>
1 -- MAX OF (date1b, date2b, date3b)<br/>
1 -- MAX OF (date1b, date2a, date3c)<br/>
1 -- MAX OF (date1b, date2b, date3c)<br/>

1 -- MAX OF (date1c, date2a, date3a)<br/>
1 -- MAX OF (date1c, date2b, date3a)<br/>
1 -- MAX OF (date1c, date2a, date3b)<br/>
1 -- MAX OF (date1c, date2b, date3b)<br/>
1 -- MAX OF (date1c, date2a, date3c)<br/>
1 -- MAX OF (date1c, date2b, date3c)<br/>
4

2 回答 2

0

我将您的变量重命名为在大多数数据库中不是保留关键字的内容:

select t1.id, t2.id, t3.id, t1.ValStr+'+'+t2.ValStr+'+'+t3.ValStr
from @TestTable2 t1 join
     @TestTable2 t2
     on t1.TheGroup < t2.TheGroup  join
     @TestTable2 t3
     on  t2.TheGroup < t3.TheGroup 

我将 SQL Server 语法用于字符串连接,因为看起来您正在使用该数据库。

我无法轻易想到在纯 SQL 查询中处理任意数量的组的方法。但是,您可以处理“最多”数量的组,例如:

select t1.id, t2.id, t3.id,
       stuff((coalesce('+'+t1.ValStr), '')+coalesce('+'+t2.ValStr, '') +
              coalesce('+'+t3.ValStr, '')+ . . .
             ), 1, 1, '')
from @TestTable2 t1 left outer join
     @TestTable2 t2
     on t1.TheGroup < t2.TheGroup left outer join
     @TestTable2 t3
     on  t2.TheGroup < t3.TheGroup . . 

您将继续左外连接到某个最大数量的组并select相应地修复该子句。

结果与您想要的有点不同。这会产生最多 n 个组的所有组合,而不是恰好 n 个组。所以第一个会产生:(3 + 2 + 3) [1 的组合] + (3 * 2 + 2 * 3 + 3 * 3) [2 的组合] + (3 * 2 * 3)。您可以通过使用这个相当麻烦的where子句来解决这个问题:

where ((case when t1.thegroup is not null then 1 else 0 end)+
       (case when t2.thegroup is not null then 1 else 0 end)+
       (case when t3.thegroup is not null then 1 else 0 end)+
       . . .
      ) = (select count(distinct thegroup) from @TestTable2)

如果您的组按顺序编号且没有间隔,您也可以将其写为:

select t1.id, t2.id, t3.id,
       stuff((coalesce('+'+t1.ValStr), '')+coalesce('+'+t2.ValStr, '') +
              coalesce('+'+t3.ValStr, '')+ . . .
             ), 1, 1, '')
from @TestTable2 t1 left outer join
     @TestTable2 t2
     on t2.TheGroup = t1.TheGroup+1 left outer join
     @TestTable2 t3
     on t3.TheGroup = t2.TheGroup+1 . . .
where t1.TheGroup = 1

实际上,即使您的组没有按顺序编号,您也可以安排此使用dense_rank()并从那里开始:

with t as (
      select t.*, dense_rank() over (order by [Group]) as TheGroup
      from @TestTable2
     )
select t1.id, t2.id, t3.id,
       stuff((coalesce('+'+t1.ValStr), '')+coalesce('+'+t2.ValStr, '') +
              coalesce('+'+t3.ValStr, '')+ . . .
             ), 1, 1, '')
from t t1 left outer join
     t t2
     on t2.TheGroup = t1.TheGroup+1 left outer join
     t t3
     on t3.TheGroup = t2.TheGroup+1 . . .
where t1.TheGroup = 1

另一种方法是使用递归 CTE。没有它,这可能是最好的仅限 SQL 的方法。

于 2013-05-10T15:42:42.620 回答
0

请参阅此SQL Fiddle

SELECT SQ1.[ID]
        ,SQ1.[VALUE]+'+'+SQ2.[VALUE]+'+'+SQ3.[VALUE] AS COMBOS
FROM
(
SELECT [id],[VALUE]
FROM TESTTABLE2
WHERE [GROUP] = 1
) SQ1
INNER JOIN
(
SELECT [id],[VALUE]
FROM TESTTABLE2
WHERE [GROUP] = 2
) SQ2
ON SQ1.[ID]= SQ2.[ID]
INNER JOIN
(
SELECT [id],[VALUE]
FROM TESTTABLE2
WHERE [GROUP] = 3
) SQ3
ON SQ1.[ID]= SQ3.[ID]
于 2013-05-10T15:41:09.137 回答