2012-11-23 25 views
4

我查看了許多解決方案以模擬SQL Server中的「組連接」功能。儘管如此,我想製作更人性化的解決方案,但我無法解決如何做到這一點。具有不同字符的SQL Server組Concat

我有一個觀點:

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個孩子,而使用','連接所有其他孩子。

我有點卡在如何做到這一點,而不訴諸CLR,我不想這樣做。我對一個功能感到滿意 - 但速度是一個問題,我如何確定孩子號碼,以便我可以在'和',','或''之間進行選擇?

+0

+1有趣的問題。而不是按父母分組孩子的數量,你想知道他們的名字顯示和concat。 :) – bonCodigo

回答

4

做出更可讀的解決方案

對不起,這是我可以與你的要求做到最好。

SQL Fiddle

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 

Results

| PARENTID |   CHILDNAMES | 
------------------------------------ 
|  1 |  Max and Jessie | 
|  2 | Steven, Lucy and Jake | 
|  3 |     Mark | 
+0

好的邏輯......回答。 – TechDo

+0

@techdo謝謝,我+1你的答案,因爲它是唯一的其他答案,實際上給了正確的輸出。哪個答案更具人性可讀性......以及它是一個關閉的呼叫:)。 –

+0

感謝Mikael。我沒有完成答案後就離開了。很高興看到你的這一個:) – bonCodigo

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

+0

AnandPhadke,我沒有看到你的答案和我的很大區別。但我被downvoted哈哈哈;) – bonCodigo

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); 
相關問題