2017-11-08 7 views
0

이 상황에서는 두 개의 테이블을 조인했습니다. 각 의사가 여러 라이센스를 가질 수 있으므로 여러 개의 중복이 작성됩니다. 필자는 아래와 같이 여러 라이선스 상태와 번호를 표 1의 추가 열로 피벗시키고 싶습니다.테이블 열을 열 값으로 조인 SQL

이것은 한 명의 의사에게 할당 된 상당한 양의 라이센스 일 수 있기 때문에 동적으로 수행해야합니다.

표 1은 이와 같이 보입니다.

assignid physician_name profession 
------------------------------- 
    1  bob   md   
    2  travis  do   
    3  ryan   md   
    4  pete   pa   
    5  susan  np   
    6  ashley  cnp  

나는 동적으로 다음과 같이 할 수있는 조인 된 테이블을 변경하려면

assignid physician_name profession license_state license_num 
---------------------------------------------------------------- 
    1  bob   md    oh   561 
    2  travis  do    mi   987 
    3  ryan   md    ca   785 
    4  pete   pa    ny   965 
    4  pete   pa    mi   125 
    5  susan  np    oh   369 
    5  susan  np    ca   541 

가입 표 2

assignid license_state license_num 
------------------------------- 
    1  oh  561 
    2  mi  987 
    3  ca  785 
    4  ny  965 
    4  mi  125 
    5  oh  369 
    5  ca  541 

.

assignid physician_name profession license_state1 license_num1 license_state2 license_num2 
-------------------------------------------------------------------------------------------------- 
    1  bob   md    oh   561 
    2  travis  do    mi   987 
    3  ryan   md    ca   785 
    4  pete   pa    ny   965    mi  125 
    5  susan  np    oh   369    ca  541 

이 경로가 시도되었지만 상태가 열 머리글로 표시됩니다.

WITH pivotdata AS (
SELECT assignid,physician_name, profession, license_state,license_num 
FROM dbo.Physicians p JOIN dbo.Licenses l ON p.AssignID = l.AssignID 
) 

SELECT * 
FROM 
    pivotdata 
    PIVOT (MAX(license_num) FOR license_state IN ([oh], [mi], [ca],[ny])) TT; 

당신은 동적 크로스 탭을 사용하여이 문제를 해결할 수

physician_name profession oh mi ca ny 
------------------------------------------- 
    bob   md   561 
    travis  do    987 
    ryan   md     785 
    pete   pa    125  965 
    susan  np   369  541 
+0

그래, 그럼 문제를 해결하려고 했습니까? – Sami

+0

@Sami 나는 내가 생각했던 것을 보여주기 위해 나의 질문을 편집했다. – smiller48

답변

0

결과. Jeff Moden과 그의 기사에서이 기술을 배웠습니다. http://www.sqlservercentral.com/articles/Crosstab/65048/

if OBJECT_ID('tempdb..#Physicians') is not null 
    drop table #Physicians 

create table #Physicians 
(
    AssignID int 
    , PhysicianName varchar(20) 
    , Profession varchar(10) 
) 

insert #Physicians values 
(1, 'bob', 'md') 
, (2, 'travis', 'do') 
, (3, 'ryan', 'md') 
, (4, 'pete', 'pa') 
, (5, 'susan', 'np') 
, (6, 'ashley', 'cnp') 

if OBJECT_ID('tempdb..#Licenses') is not null 
    drop table #Licenses 

create table #Licenses 
(
    AssignID int 
    , LicenseState char(2) 
    , LicenseNum int 
) 

insert #Licenses values 
(1, 'oh', 561) 
, (2, 'mi', 987) 
, (3, 'ca', 785) 
, (4, 'ny', 965) 
, (4, 'mi', 125) 
, (5, 'oh', 369) 
, (5, 'ca', 541) 

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as 
    (
     SELECT p.AssignID 
      , p.PhysicianName 
      , p.Profession 
      , l.LicenseState 
      , l.LicenseNum 
      , ROW_NUMBER() over(partition by p.AssignID order by l.LicenseState) as RowNum 
     FROM #Physicians p 
     JOIN #Licenses l ON p.AssignID = l.AssignID 
    ) 
    select AssignID'; 

declare @DynamicPortion nvarchar(max) = ''; 
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by AssignID order by AssignID'; 

--the following cte is a tally table (another trick I learned from Jeff Moden) 
with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)), 
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows 
cteTally(N) AS 
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E2 
) 

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then LicenseState end) as LicenseState' + CAST(N as varchar(6)) + CHAR(10) 
    + ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then LicenseNum end) as LicenseNum' + CAST(N as varchar(6)) + CHAR(10) 
from cteTally t 
where t.N <= 
(
    select top 1 Count(p.AssignID) 
    FROM #Physicians p 
    JOIN #Licenses l ON p.AssignID = l.AssignID 
    group by p.AssignID 
    order by COUNT(*) desc 
) 


declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion; 

--you can comment the following. it is here for now so you can view the dynamic sql before it executes 
select @SqlToExecute 

--Once you are satisfied that the dynamic sql generated is correct simply uncomment the below line 
--exec sp_executesql @SqlToExecute 
+0

감사합니다. 이것은 정확하게 내가하려고했던 것입니다! @SeanLange – smiller48

+0

이것이 작동하는 경우 이것을 대답으로 표시하는 것이 좋습니다. 하지만 더 중요한 것은, 거기에 무슨 일이 일어나고 있는지 이해합니까? –