2015-04-15 143 views
2

我想將多行組合成單行,我能夠得到它的一半,我嘗試了很多方法獲得剩餘的一半,下面是我寫的SQL。任何幫助將不勝感激。將多條記錄(行)合併爲單條記錄(行)

DROP TABLE #TEST_DEPT_NAME 

CREATE TABLE #TEST_DEPT_NAME ([ID] [varchar](255) NULL,[CSN_ID] [varchar](50) NULL,[NOTE_ID] [varchar](50) NULL,[DEPARTMENT_NAME] [varchar](255) NULL, 
[NOTE_CSN_ID] [varchar](50) NULL,[LINE] [varchar](50) NULL,[NOTE_TEXT] [nvarchar](max) NULL,[AUTHOR_USER_ID] [varchar](50) NULL,[AUTHOR_USER_NAME] [varchar](255) NULL, 
[NOTE_TYPE_NAME] [varchar](255) NULL,[IS_ARCHIVED_YN] [varchar](255) NULL,[NOTE_STATUS_NAME] [varchar](255) NULL) 

INSERT INTO #TEST_DEPT_NAME 
VALUES ('123456','1234567','12345678' ,'TEST','0' ,1 ,'NOTES_1.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,1 ,'NOTES_1.1.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,2 ,'NOTES_1.2' ,'999999','TEST 1','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,3 ,'NOTES_1.3' ,'999999','TEST 1','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,1 ,'NOTES_2.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,2 ,'NOTES_2.2' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,3 ,'NOTES_2.3' ,'1234','TEST','Clinic Note','N','Signed') 


SELECT distinct ID,[CSN_ID],[NOTE_ID],[DEPARTMENT_NAME],[NOTE_TYPE_NAME],[IS_ARCHIVED_YN] 
,[NOTE_TEXT] = (select ' '+ case when [NOTE_TEXT]= '' then null else [NOTE_TEXT]end from #TEST_DEPT_NAME P1 
WHERE P1.[ID] = P2.[ID]AND P1.[CSN_ID] =P2.[CSN_ID] AND P1.NOTE_ID = P2.NOTE_ID AND P1.DEPARTMENT_NAME = P2.DEPARTMENT_NAME 
AND P1.LINE = P2.LINE AND P1.NOTE_TYPE_NAME =P2.NOTE_TYPE_NAME AND P1.NOTE_CSN_ID = P2.NOTE_CSN_ID AND P1.IS_ARCHIVED_YN =P2.IS_ARCHIVED_YN FOR XML PATH('')) 
FROM #TEST_DEPT_NAME P2 WHERE [ID] = '123456' 
GROUP BY ID,CSN_ID,[NOTE_ID],[DEPARTMENT_NAME],[NOTE_TYPE_NAME],[IS_ARCHIVED_YN],LINE,NOTE_CSN_ID 

當我運行上面的SQL我得到的結果集如下

ID  CSN_ID NOTE_ID DEPARTMENT_NAME NOTE_TEXT 
123456 1234567 12345678 TEST    NOTES_1.1 NOTES_1.1.1 
123456 1234567 12345678 TEST    NOTES_1.2 
123456 1234567 12345678 TEST    NOTES_1.3 
123456 1234567 12345678 TEST    NOTES_2.1 
123456 1234567 12345678 TEST    NOTES_2.2 
123456 1234567 12345678 TEST    NOTES_2.3 

但我想如下圖所示

ID  CSN_ID NOTE_ID  DEPARTMENT_NAME NOTE_TEXT 
123456 1234567 12345678 TEST    NOTES_1.1 NOTES_1.1.1 NOTES_1.2 NOTES_1.3 
123456 1234567 12345678 TEST    NOTES_2.1 NOTES_2.2 NOTES_2.3 

回答

1

您可以使用leftstuff個功能與group by

select t.ID ,t.CSN_ID,t.NOTE_ID,t.DEPARTMENT_NAME, 
     STUFF((
     select ' ' + t1.NOTE_TEXT 
     from #TEST_DEPT_NAME t1 
     where t.ID =t1.ID and t.CSN_ID=t1.CSN_ID and t.NOTE_ID=t1.NOTE_ID 
       and t.DEPARTMENT_NAME=t1.DEPARTMENT_NAME 
       and left(t.NOTE_TEXT,8)=left(t1.NOTE_TEXT,8) 
     for xml path(''), type 
    ).value('.', 'varchar(max)'), 1, 1, '') NOTE_TEXT_ 
from #TEST_DEPT_NAME t 
group by t.ID ,t.CSN_ID,t.NOTE_ID,t.DEPARTMENT_NAME,left(t.NOTE_TEXT,8) 

輸出:

ID  CSN_ID NOTE_ID  DEPARTMENT_NAME NOTE_TEXT_ 
123456 1234567 12345678 TEST   NOTES_1.1 NOTES_1.1.1 NOTES_1.2 NOTES_1.3 
123456 1234567 12345678 TEST   NOTES_2.1 NOTES_2.2 NOTES_2.3 

編輯:如果你有超過9 NOTE_TEXT我的意思是NOTES_1..,NOTES_2...,NOTES_10...,NOTES_100...,那麼你必須在上面的查詢使用charindex('.',t.NOTE_TEXT)代替8

select t.ID ,t.CSN_ID,t.NOTE_ID,t.DEPARTMENT_NAME, 
     STUFF((
     select ' ' + t1.NOTE_TEXT 
     from #TEST_DEPT_NAME t1 
     where t.ID =t1.ID and t.CSN_ID=t1.CSN_ID and t.NOTE_ID=t1.NOTE_ID 
       and t.DEPARTMENT_NAME=t1.DEPARTMENT_NAME 
       and left(t.NOTE_TEXT,charindex('.',t.NOTE_TEXT)) 
        =left(t1.NOTE_TEXT,charindex('.',t1.NOTE_TEXT)) 
     for xml path(''), type 
    ).value('.', 'varchar(max)'), 1, 1, '') NOTE_TEXT_ 
from #TEST_DEPT_NAME t 
group by t.ID ,t.CSN_ID,t.NOTE_ID,t.DEPARTMENT_NAME, 
     left(t.NOTE_TEXT,charindex('.',t.NOTE_TEXT)) 
+1

你假設的數據是真實的數據。你開始砍掉文本字段和id字段,以加入你爲受傷的世界而加入。最好使用好的設計來確保數據正確分離,而不是對字段值做出假設。 在這種情況下,有一個csn_note_id和一個行字段。在一個好的設計中,一個表示一個組中的所有音符,另一個表示父/子關係中每個音符的行。通過在創建行時增加csn_note_id,可以減少這種關係,並且不能再將註釋行分組在一起。 – TDavis

+1

感謝您的回答,這是工作正常,直到發現此問題。如果我們查看錶(ID,CSN_ID,NOTE_ID,DEPT_NAME)中的數據將具有相同的數據,但是當NOTE_CSN_ID更改LINE值更改並且NOTE_TEXT更改時。 LINE字段中的值不一致,有時我首先將LINE 3放入數據庫中,然後LINE 1,我想要按LINE(1,2,3)順序放置結果集。請幫助我解決這個問題。 – user3311323

+1

@ user3311323歡迎您,但是我沒有讓你很好,但是你說LINE字段中的值不一致,所以如果你按LINE分組,那麼肯定你不會得到期望的結果,因爲它有多個值每個特定的組在你想要的輸出中,但是如果你想用LINE排序,你需要在查詢中使用它(使用子查詢或者你可能想要連接行)[見本演示](http:// sqlfiddle。 com /#!6/3b78a/6),希望這些有用的 – jfun

1

我的假設的結果是,這是弗利數據和Note_Text的值實際上是由用戶輸入的長形註釋。 note_csn_id字段中的值和分組中包含的行使查詢分離出單獨的「Note_1」記錄。

你查詢產生的#test_dept_name以下結果:

ID  CSN_ID  NOTE_ID  DEPARTMENT_NAME  NOTE_CSN_ID  LINE NOTE_TEXT  AUTHOR_USER_ID AUTHOR_USER_NAME NOTE_TYPE_NAME IS_ARCHIVED_YN NOTE_STATUS_NAME 
123456 1234567  12345678 TEST    1234   1  NOTES_1.1  1234   TEST    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    1234   1  NOTES_1.1.1  1234   TEST    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    12345   2  NOTES_1.2  999999   TEST 1    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    123456   3  NOTES_1.3  999999   TEST 1    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    66666   1  NOTES_2.1  1234   TEST    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    66666   2  NOTES_2.2  1234   TEST    Clinic Note  N    Signed 
123456 1234567  12345678 TEST    66666   3  NOTES_2.3  1234   TEST    Clinic Note  N    Signed 

注意note_csn_id更改時記行更改。這可能是多餘的行爲,因爲您有單獨的行號。我們可以查詢出來,你的願望:

  • by子句改變組只考慮第X note_csn_id的 (一般是一個糟糕的主意,因爲ID字段往往 成長長)
  • 改變note_csn_id的填充方式,使其 獨特的票據的每個分組(好主意,如果你有超過note_csn_id如何填充控制)

在這兩種情況下,您還需要去掉從上線的連接b組中的子選擇和刪除行y子句。

如果你能做出改變如何note_csn_id填充,使得它看起來像這樣:

INSERT INTO #TEST_DEPT_NAME 
VALUES ('123456','1234567','12345678' ,'TEST','0' ,1 ,'NOTES_1.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,1 ,'NOTES_1.1.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,2 ,'NOTES_1.2' ,'999999','TEST 1','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','0' ,3 ,'NOTES_1.3' ,'999999','TEST 1','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,1 ,'NOTES_2.1' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,2 ,'NOTES_2.2' ,'1234','TEST','Clinic Note','N','Signed') 
,('123456','1234567','12345678' ,'TEST','66666' ,3 ,'NOTES_2.3' ,'1234','TEST','Clinic Note','N','Signed') 

然後你可以選擇更改爲以下:

SELECT distinct 
ID, 
[CSN_ID], 
[NOTE_ID], 
[DEPARTMENT_NAME], 
[NOTE_TYPE_NAME], 
[IS_ARCHIVED_YN], 
[NOTE_TEXT] = (select ' '+ case when [NOTE_TEXT]= '' then null else [NOTE_TEXT]end from #TEST_DEPT_NAME P1 
WHERE P1.[ID] = P2.[ID]AND P1.[CSN_ID] =P2.[CSN_ID] AND P1.NOTE_ID = P2.NOTE_ID AND P1.DEPARTMENT_NAME = P2.DEPARTMENT_NAME 
AND P1.NOTE_TYPE_NAME =P2.NOTE_TYPE_NAME AND P1.NOTE_CSN_ID = P2.NOTE_CSN_ID AND P1.IS_ARCHIVED_YN =P2.IS_ARCHIVED_YN FOR XML PATH('')) 

FROM #TEST_DEPT_NAME P2 WHERE [ID] = '123456' 

GROUP BY ID,CSN_ID,[NOTE_ID],[DEPARTMENT_NAME],[NOTE_TYPE_NAME],[IS_ARCHIVED_YN],NOTE_CSN_ID 

,並得到此結果:

ID  CSN_ID NOTE_ID  DEPARTMENT_NAME NOTE_TYPE_NAME IS_ARCHIVED_YN NOTE_TEXT 
123456 1234567 12345678 TEST   Clinic Note  N    NOTES_1.1 NOTES_1.1.1 NOTES_1.2 NOTES_1.3 
123456 1234567 12345678 TEST   Clinic Note  N    NOTES_2.1 NOTES_2.2 NOTES_2.3 
1

我覺得這個查詢所需的一個:

SELECT distinct ID,[CSN_ID],[NOTE_ID],[DEPARTMENT_NAME],[NOTE_TEXT] = 
(
select ' '+ case when [NOTE_TEXT]= '' then null else [NOTE_TEXT]end 
from #TEST_DEPT_NAME P1 
WHERE P1.[ID] = P2.[ID] 
AND P1.[CSN_ID] =P2.[CSN_ID] 
AND P1.NOTE_ID = P2.NOTE_ID 
AND P1.DEPARTMENT_NAME = P2.DEPARTMENT_NAME 
AND P1.NOTE_TYPE_NAME =P2.NOTE_TYPE_NAME 
AND P1.IS_ARCHIVED_YN =P2.IS_ARCHIVED_YN 
AND SUBSTRING(P1.NOTE_TEXT, 0, CHARINDEX('.', P1.NOTE_TEXT)) = SUBSTRING(P2.NOTE_TEXT, 0, CHARINDEX('.', P2.NOTE_TEXT)) 
FOR XML PATH('') 
) 
FROM #TEST_DEPT_NAME P2 WHERE [ID] = '123456' 
GROUP BY ID,CSN_ID,[NOTE_ID],[DEPARTMENT_NAME],[NOTE_TYPE_NAME],[IS_ARCHIVED_YN],LINE,NOTE_CSN_ID,SUBSTRING([NOTE_TEXT], 0, CHARINDEX('.', [NOTE_TEXT])) 

結果:

ID  CSN_ID NOTE_ID  DEPARTMENT_NAME NOTE_TEXT 
123456 1234567 12345678 TEST    NOTES_1.1 NOTES_1.1.1 NOTES_1.2 NOTES_1.3 
123456 1234567 12345678 TEST    NOTES_2.1 NOTES_2.2 NOTES_2.3