简体   繁体   中英

SQL CTE for one-to-many relationship

I have two tables

1) Is the applicant name so it would look like this

ID | ApplicantName
_____________________________
1  | 'Joe Schmoe'    
2  | 'Jimmy Dean' 

2) Is the applicants questions so it would look like this

ID | ApplicantId | QuestionId | QuestionAnswer
_________________________________________________
1  |      1      |     1      |   'PF CHANGS'
2  |      1      |     2      |   'Toyota'
3  |      2      |     1      |   'Burger King'
4  |      2      |     2      |   'Honda'

So I query it and I get these results:

ApplicantName | QuestionId | QuestionAnswer
_________________________________________________
'Joe Schmoe'  |     1      |   'PF CHANGS'
'Joe Schmoe'  |     2      |   'Toyota'
'Jimmy Dean'  |     1      |   'Burger King'
'Jimmy Dean'  |     2      |   'Honda'

But that's not what I want I want something like this if possible using the AS clause:

ApplicantName | Answer1       |  Answer2
_________________________________________________
'Joe Schmoe'  | 'PF CHANGS'   | 'Toyota'
'Jimmy Dean'  | 'Burger King' | 'Honda'

I have no idea how to achieve this.

I've looked up things like MAx() and COUNT() but those don't work something about aggregates not working.

-- I GUESS THIS IS AS CLOSE AS I GOT BUT IT FAILS

SELECT g.ApplicantName,  MAX(CAST(c.QuestionAnswer as varchar(MAX))) AS Questions
FROM Forms f
INNER JOIN GeneralQuestions g ON f.FormId = g.FormId
LEFT JOIN CustomQuestions c ON f.FormId = c.FormId
GROUP BY c.QuestionAnswer
--ORDER BY g.ApplicantName ASC

With CTEs and joins:

with cteAppl(id, name)
as
(
    select
        id, name
    from
    (
        values
          (1,  'Joe Schmoe'),   
          (2,  'Jimmy Dean') 
    ) vals(id, name)
),
ctePositions(applicantID, questionID, questionAnswer)
as
(
    select 
        applicantID, questionID, questionAnswer
    from
    (
        values
          (1, 1,  'PF CHANGS'),
          (1, 2,  'Toyota'),
          (2, 1,   'Burger King'),
          (2, 2,  'Honda')
    ) vals(applicantID, questionID, questionAnswer)
),
ctePositions1(applicantID, questionID, questionAnswer)
as
(
    select 
        applicantID, questionID, questionAnswer
    from
        ctePositions
    where
        questionID = 1
),
ctePositions2(applicantID, questionID, questionAnswer)
as
(
    select 
        applicantID, questionID, questionAnswer
    from
        ctePositions
    where
        questionID = 2
)
select
    a.[name], 
    p1.questionAnswer as Answer1,
    case when p2.questionAnswer is null then '' else p2.questionAnswer end as Answer2
from
    cteAppl a
inner join
    ctePositions1 p1 on a.id = p1.applicantID
left join
    ctePositions2 p2 on a.id = p2.applicantID

With the T-SQL PIVOT operator:

with cteAppl(id, [name])
as
(
    select
        id, name
    from
    (
        values
          (1,  'Joe Schmoe'),   
          (2,  'Jimmy Dean') ,
    ) vals(id, name)
),
ctePositions(applicantID, answerID, questionAnswer)
as
(
    select 
        applicantID, answerID, questionAnswer
    from
    (
        values
          (1, 1,  'PF CHANGS'),
          (1, 2,  'Toyota'),
          (2, 1,  'Burger King'),
          (2, 2,  'Honda'),
    ) vals(applicantID, answerID, questionAnswer)
)
select
    cpvt.applicantName,
    cp1.questionAnswer as [Answer1],
    cp2.questionAnswer as [Answer2]  
from
(
    select
        [name],
        applicantID,
        pvt.answer1,
        pvt.answer2
    from
    (
        select
            a.[name],
            p.applicantID,      
            case 
                when p.answerID = 1 then 'answer1'
                when p.answerID = 2 then 'answer2'
                else ''
            end as generatedColumnName, 
            p.answerID
        from
            cteAppl a
        inner join
            ctePositions p on a.id = p.ApplicantID
    ) as st ([name], applicantID, [generatedColumnName], [answerID])
    PIVOT 
    (
           MAX(st.answerID) -- Must use an aggregate function here
           for generatedColumnName in ([answer1], [answer2]) 
    ) as pvt
) cpvt (applicantName, applicantID, answer1ID, answer2ID)
left join
    ctePositions cp1 on cp1.applicantID = cpvt.applicantID and cp1.answerID = cpvt.answer1ID
left join
    ctePositions cp2 on cp2.applicantID = cpvt.applicantID and cp2.answerID = cpvt.answer2ID

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM