0

異なるグループの SUM を持つ ID に従って、行の順列と組み合わせが必要です: 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 です。

OutPut は次のように必要です: 3*2*3 の異なるグループ行 (ここでは Group1、Group2、および Group3 の場合) からの 18 の組み合わせで、その 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

この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 に答える
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

もう 1 つのアプローチは、再帰的な CTE を使用することです。それがなければ、これはおそらく最良の SQL のみのアプローチです。

于 2013-05-10T15:42:42.620 に答える