문제

나는 바닥에 도달 할 수없는 집계 문제에 갇혀 있습니다.

다음과 같이 가장 잘 요약 된 데이터가 있습니다.

id |phraseId|seqNum|word
=========================
1  |1       |1     |hello
2  |1       |2     |world
3  |2       |1     |black
4  |2       |2     |and
5  |2       |3     |white

다음 데이터를 돌려주는 쿼리를 원합니다.

phraseId|completePhrase
========================
1       |hello world
2       |black and white

누구나?

편집하다

제공된 모든 솔루션이 사용되는 것을 알 수 있습니다 FOR XML PATH. 이 마법은 무엇입니까?

도움이 되었습니까?

해결책

한 가지 해결책은 UDF 사용 XML 경로의 경우 표현.

  • UDF는 하나의 문자의 연결을 처리합니다
  • 정상적인 선택에서 사용할 수 있습니다

SQL 문

SELECT  PhraseID, dbo.UDF_ConcatWord(PhraseID)
FROM    Phrases
GROUP BY PhraseID

UDF 생성

CREATE FUNCTION dbo.UDF_ConcatWord(@phraseID INT) RETURNS VARCHAR(8000) AS
BEGIN  
  DECLARE @r VARCHAR(8000)
  SELECT @r = (
    SELECT  word + ', '
    FROM    Phrases
    WHERE   phraseID = @phraseID
    FOR XML PATH('')
  )
  IF LEN(@r) > 0 SET @r = SUBSTRING(@r, 1, LEN(@r)-1)
  RETURN @r
END
GO

편집하다

일부 링크를 직접 수정 한 후에는 더 짧은 솔루션이

SQL 문

SELECT  DISTINCT p1.PhraseID
        , STUFF(( SELECT  ' ' + p2.word 
                  FROM    Phrases AS p2 
                  WHERE   p2.PhraseID = p1.PhraseID 
                  FOR XML PATH('')), 1, 1, '') AS completePhrase
FROM      Phrases AS p1
ORDER BY  p1.PhraseID

다른 팁

이 시도:

DECLARE @TableA  table (RowID int, phraseId varchar(5),seqNum int, word varchar(5))

INSERT INTO @TableA VALUES (1,1,1,'hello')
INSERT INTO @TableA VALUES (2,1,2,'world')
INSERT INTO @TableA VALUES (3,2,1,'black')
INSERT INTO @TableA VALUES (4,2,2,'and')
INSERT INTO @TableA VALUES (5,2,3,'white')

SELECT
    c1.phraseId
        ,STUFF(
                 (SELECT
                      ' ' + word
                      FROM @TableA  c2
                      WHERE c2.phraseId=c1.phraseId
                      ORDER BY c1.phraseId, seqNum
                      FOR XML PATH('') 
                 )
                 ,1,1, ''
              ) AS CombinedValue
    FROM @TableA c1
    GROUP BY c1.phraseId
    ORDER BY c1.phraseId

산출:

phraseId CombinedValue
-------- --------------------------
1        hello world
2        black and white

(2 row(s) affected)

각 문구에 대한 헤더 레코드를 보유하는 테이블이 있다고 가정하여 조금 부정했습니다. 누락 된 경우, 단어가 포함 된 테이블에서 뚜렷한 문구 목록을 선택하여 구성 할 수 있습니다.

declare @words table
(id int
,phraseId int
,seqNum int
,word varchar(10)
)

insert @words
select 1,1,1,'hello'
union select 2,1,2,'world'
union select 3,2,1,'black'
union select 4,2,2,'and'
union select 5,2,4,'white'

declare @phrase table
(phraseId int)

insert @phrase
select 1
union select 2

select phraseID
       ,phraseText AS completePhrase
FROM @phrase AS p
CROSS APPLY (select word + ' ' as [text()]
             from @words AS w
             where w.phraseID = p.phraseID
             for xml path('')
            ) as phrases (phraseText)

결국 나는 Lieven의 두 번째 대답을 사용했지만 특정 문자열 조합에 대해 FOR XML PATH('') 속임수는 문제가 발생합니다.

declare @phrases table
(
    id int
    ,phraseId int
    ,seqNum int
    ,word varchar(10)
)

insert 
    @phrases 
values
    (1,1,1,'hello'),
    (2,1,2,'world'),
    (3,2,1,'black'),
    (4,2,2,'and'),
    (5,2,3,'white')

SELECT  
    DISTINCT p1.PhraseID, 
    STUFF(
        ( 
            SELECT  
                ' ' + p2.word 
            FROM    
                @phrases AS p2 
            WHERE   
                p2.PhraseID = p1.PhraseID 
            FOR XML PATH('')
        ), 1, 1, '') AS completePhrase
FROM      
    @phrases AS p1
ORDER BY  
    p1.PhraseID

잘 작동하지만이 예제가 탈출이 필요한 문자를 사용하면 XML에 사용 된 경우 문제가 발생합니다. 예를 들어, 다음을 통해 다음 데이터를 실행합니다.

insert 
    @words 
values
    (1,1,1,'hello>'), --notice the less than symbol
    (2,1,2,'world'),
    (3,2,1,'black')

주어진

hello> world

또한 소스 테이블이 순서대로 선언되면 order by 필요합니다

원래 쿼리에 대한 작은 모드는 모든 것을 수정합니다.

SELECT  
    DISTINCT p1.PhraseID, 
    STUFF(
        ( 
            SELECT  
                ' ' + p2.word 
            FROM    
                @words AS p2 
            WHERE   
                p2.PhraseID = p1.PhraseID 
            ORDER BY
                p2.seqNum  --required
            FOR XML PATH(''),TYPE
        ).value('.','nvarchar(4000)'), 
        1, 
        1, 
        ''
    ) AS completePhrase
FROM      
    @words AS p1
ORDER BY  
    p1.PhraseID

(보다 XML Path ( '') 용 : "특별"문자를 이사)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top