2017-12-11 15 views
0

아래와 같은 테이블에서 피벗을 실행하려고합니다.동일한 값을 반환하는 SQL 피벗

Item Barcode Primary 
Test1 111111 Y 
Test1 222222 N 
Test1 333333 N 
Test1 444444 N 
Test2 999999 Y 
Test2 888888 N 
Test2 777777 N 
Test2 666666 N 

다음과 같은 표를 만들려고합니다. 아래의 쿼리를 사용하여 (열 당 하나의 바코드)

Item Primary Sec1 Sec2 Sec3 
Test1 111111 222222 333333 444444 
Test2 999999 888888 777777 666666 

는 내가 차 열과 첫 번째 보조 열을 채울 수 있습니다,하지만 난 자신의 열까지 다른 보조 코드를 가져올 수있는 방법을 찾을 수 없습니다. 대신 아래의 첫 번째 보조 바코드를 반복합니다.

Item Primary Barcode Secondary 1 Secondary3 
Test1 111111 222222 222222 
Test2 999999 888888 888888 

select item, [Y] as 'Primary', [N] as 'Sec1', [N] as 'Sec2' 
from 
(
    select ics.itemcoloursize_id as item, sc.sellcode_code as code, sc.primary_ind as ind 
    from sellcode sc 
    left join itemcoloursize ics on ics.itemcoloursize_id = sc.itemcoloursize_id 
    where ics.itemcoloursize_id in 
    (
    's+0015p00fhb' 
    ) 
) as Barcodes 
PIVOT 
(
    max(code) 
    for ind in ([Y],[N]) 
    ) 
    as PVT 

어떤 도움을 주시면 감사하겠습니다.

+0

222222가 Sec2가 아니라 어떻게 Sec1이어야하는지 어떻게 알 수 있습니까? 행을 정렬하는 다른 열이 있습니까? – DancingFool

+0

primary_ind = 'N'인 모든 바코드는 자체 열에 Sec1-x로 나타나야합니다. 이것들의 순서는 중요하지 않습니다. – Roger123

답변

1

당신이 pivot 또는 일부 동적 접근 방식으로 가고 싶어하지 않는 경우 case 표현의 도움으로 조건부 집계를 시도 할 수

select Item, 
     max(case when [Primary] = 'Y' then Barcode else null end) [Primary], 
     max(case when ([Primary] = 'N' AND [RN] = 1) then Barcode else null end) [Sec1], 
     max(case when ([Primary] = 'N' AND [RN] = 2) then Barcode else null end) [Sec2], 
     max(case when ([Primary] = 'N' AND [RN] = 3) then Barcode else null end) [Sec3] 
     from 
(
    select *, row_number() over (partition by Item, [Primary] order by Item) [rn] from table 
) t 
group by Item 

결과 :

Item Primary Sec1 Sec2 Sec3 
Test1 111111 222222 333333 444444 
Test2 999999 888888 777777 666666 
0

이 시도 될 수있다 당신에게 도움이됩니다.

해결책 :

item Primry sec1 sec2 sec3 Test 1 111111 222222 333333 444444 Test 2 999999 888888 777777 666666

+0

위의 두 가지 제안을 모두 시도했습니다. 나도 나를 위해 일할 능력이 없다. 다른 도움을 주시면 감사하겠습니다. – Roger123

0

보십시오

다음

select item,parsename(commasep,4)Primry,parsename(commasep,3)sec1, 
    parsename(commasep,2)sec2,parsename(commasep,1)sec3 
    from 
    (select item,stuff((select '.' + u.barcode from pivottest u 
    where u.item = p.item order by u.isprimary desc 
    for xml path('')),1,1,'') as commasep 
    from pivottest p group by item) as parsecommasep 

RESULT parsename 함수를 사용하여 개별 항목으로서 바코드를 구분 항목별로 도트 세퍼레이터기로 바코드 값을 결합 이 스크립트는 오류 또는 출력이 다른 샘플 데이터와 맞지 않으면 알 수 있습니다.

또한 다른 일에 따라 더욱 최적화 될 수 그렇네 여기 #T 당신의 table.leave의 #TT가 sp_executesql

CREATE TABLE #t (Item VARCHAR(50) 
,Barcode VARCHAR(50),Primarys CHAR(1)) 

INSERT INTO #t VALUES 
('Test1','111111','Y') 
,('Test1','222222','N') 
,('Test1','333333','N') 
,('Test1','444444','N') 
,('Test2','999999','Y') 
,('Test2','888888','N') 
,('Test2','777777','N') 
--,('Test2','666666','N') 

--SELECT * FROM #t 

DECLARE @ColValue VARCHAR(500) 
DECLARE @ColName VARCHAR(500) 

;WITH CTE 
AS (
    SELECT Item 
     ,Barcode 
     ,Primarys 
     ,ROW_NUMBER() OVER (
      PARTITION BY item ORDER BY item 
      ) rn 
    FROM #t 
    ) 
    ,CTE1 
AS (
    SELECT Item 
     ,Barcode 
     ,Primarys 
     ,rn 
     ,CASE 
      WHEN Primarys = 'Y' 
       THEN 'Primary' 
      ELSE 'Sec' + cast(rn - 1 AS VARCHAR) 
      END Headers 
    FROM cte 
    ) 
SELECT * 
INTO #tt 
FROM cte1 


SELECT @ColName = stuff((
      SELECT ',[' + Headers + ']' 
      FROM #tt t1 
      WHERE t.Item = t1.Item 
      FOR XML PATH('') 
      ), 1, 1, '') 
FROM #tt t 
ORDER BY rn 

--SELECT @ColName 
DECLARE @Sql VARCHAR(500) = '' 

SET @Sql = ' 
select item,' + @ColName + ' from 
(
select item,Barcode,Headers from #tt 
)base 
pivot(max(Barcode) for Headers in(' + @ColName + ')) as pvt 
' 

PRINT @sql 

EXEC (@Sql) 

DROP TABLE #tt 

DROP TABLE #t 

를 사용하는 것이 좋습니다.