4

SQL Server で「グループ連結」機能をエミュレートするための多くのソリューションを検討しました。私はもっ​​と人間が読める解決策を作りたかったのですが、それを行う方法がわかりません。

私は見解を持っています:

ParentID | ChildName

たとえば、次のようなレコードが含まれます。

1 | Max
1 | Jessie
2 | Steven
2 | Lucy
2 | Jake
3 | Mark

これらを「グループ連結」して取得したい:

1 | Max and Jessie
2 | Steven, Lucy and Jake
3 | Mark

したがって、子が 1 つしかない場合は名前を返し、複数ある場合は最後の 2 つを「and」で連結し、他のすべてを「,」で連結します。

私はやりたくないCLRに頼らずにこれを行う方法に少しこだわっています。関数には満足していますが、速度が問題であり、' と '、'、' または '' のいずれかを選択できるように子番号を決定するにはどうすればよいですか?

4

3 に答える 3

4

より人間が読めるソリューションを作成する

申し訳ありませんが、これがあなたの要件に対して私ができる最善のことです.

SQL フィドル

MS SQL Server 2008 スキーマのセットアップ:

create table YourTable
(
  ParentID int,
  ChildName varchar(10)
);

insert into YourTable values
(1, 'Max'),
(1, 'Jessie'),
(2, 'Steven'),
(2, 'Lucy'),
(2, 'Jake'),
(3, 'Mark');

クエリ 1 :

with T as 
(
  select ParentID,
         ChildName,
         row_number() over(partition by ParentID order by ChildName) as rn,
         count(*) over(partition by ParentID) as cc
  from YourTable
)
select T1.ParentID,
       (
         select case
                  when T2.rn = 1 and T2.cc > 1 then ' and '
                  else ', ' 
                end + T2.ChildName
         from T as T2
         where T1.ParentID = T2.ParentID
         order by T2.rn desc
         for xml path(''), type
       ).value('substring(text()[1], 3)', 'varchar(max)') as ChildNames
from T as T1
group by T1.ParentID

結果

| PARENTID |            CHILDNAMES |
------------------------------------
|        1 |        Max and Jessie |
|        2 | Steven, Lucy and Jake |
|        3 |                  Mark |
于 2012-11-23T06:32:38.243 に答える
1
select ParentID,STUFF((SELECT ' and '+ChildName
    FROM Table1 where ParentID=a.ParentID
     FOR XML PATH('')),1,4,'')  as cnmae from Table1 a
group by ParentID

SQL FIDDLE DEMO

于 2012-11-23T06:10:43.460 に答える
1

良い論理的な質問. 以下のクエリを確認してください(少し長いですが、私の小さなロジックを投稿するのをやめられませんでした:))。

CREATE TABLE #SampleTable ([ParentID] int, [ChildName] varchar(6));

INSERT INTO #SampleTable VALUES (1, 'Max')
INSERT INTO #SampleTable VALUES (1, 'Jessie')
INSERT INTO #SampleTable VALUES (2, 'Steven')
INSERT INTO #SampleTable VALUES (2, 'Lucy')
INSERT INTO #SampleTable VALUES (2, 'Jake')
INSERT INTO #SampleTable VALUES (3, 'Mark')

select * From #SampleTable

;WITH T(xParentID, xChildName, xChildNameResult, xC1, xC2)AS
(
    SELECT * FROM(
    SELECT 
        ParentID ,
        ChildName, 
        CAST(ChildName AS NVARCHAR(MAX)) AS ChildNameResult,
        ROW_NUMBER() OVER (PARTITION BY [ParentID] ORDER BY ChildName) C1,
        COUNT(*) OVER (PARTITION BY [ParentID]) C2
    FROM #SampleTable)x WHERE x.C1=1

    UNION ALL

    SELECT ParentID, ChildName,
    CAST(T.xChildNameResult+(CASE WHEN C1=1 THEN '' WHEN C1=C2 THEN ' and ' ELSE ', ' END)+ChildName AS NVARCHAR(MAX)), C1, C2 
    FROM
    (
        SELECT 
        ParentID , 
            ChildName, 
            ROW_NUMBER() OVER (PARTITION BY ParentID order by ChildName) C1,
            COUNT(*) OVER (PARTITION BY ParentID) C2
        FROM #SampleTable
    )y INNER JOIN T ON y.ParentID=T.xParentID and y.c1=T.xC1+1
)SELECT xParentID, xChildNameResult FROM T where xC1=xC2
OPTION (MAXRECURSION 0);
于 2012-11-23T06:38:51.430 に答える