user3648426
user3648426

Reputation: 251

SQL Case with conditional display

I am trying to write a query that will return 1 row for each 'Applicant' with a column that will display the employerId for the applicant if the number of employerIds is 1, otherwise it would return a string on that column saying "Multiple Applications". Please see below, I am working with MSSQL. Could someone guide me towards the right direction?

    Table: Applicant

    ID | FirstName | LastName
    ----------------------------
    01 | John      | Smith
    02 | Mark      | Doe
    03 | George    | Washington



    Table: Employer

    ID | ApplicantId | EmployerId
    ----------------------------
    01 | 01          | 100
    02 | 01          | 103
    03 | 02          | 101
    04 | 03          | 106


    Desired Output:

    FirstName | LastName   | Employer
    ---------------------------------
    John      | Smith      | Multiple Applications
    Mark      | Doe        | 101
    George    | Washington | 106

Thanks!

Upvotes: 2

Views: 77

Answers (3)

shawnt00
shawnt00

Reputation: 17915

select
    min(FirstName) as FirstName,
    min(LastName) as LastName,
    case
        when count(*) > 1 then 'Multiple Applications'
        else cast(min(EmployerId) as varchar(11))
    end as Employer
from Applicant as a inner join Employer as e on e.ApplicantId = a.Id
group by a.Id

It's certainly possible that you could have multiple applicants with the same name, especially just last name. So you wouldn't want to group on those columns without grouping on the applicant id.

Many people like to add extra group columns to avoid the need for a dummy aggregate expression on column from the one side of a 1:M join. (And other platforms allow you to refer to a constant or "functionally dependent" column without the aggregate at all.) I personally think that that approach masks the intent of the query. Those extra grouping could potentially change the query plan and/or performance.

This case is interesting because we have to use a dummy aggregate inside the case expression anyway. So it makes that much more sense to mirror it in the first and last name columns as well.

Upvotes: 1

Ali Adravi
Ali Adravi

Reputation: 22723

Select *
 ,  CASE WHEN 
        (Select COUNT(ApplicantId) From Employer 
        Where Employer.ApplicantId = Applicant.ID) =  1 
    THEN CAST(Applicant.ID AS varchar) 
    ELSE 'Multiple Applications' ENd AS [Applicant]
From Applicant

Upvotes: 0

Richard
Richard

Reputation: 30618

You can use a simple grouping and make use of MIN to get the value when there's only one item:

SELECT Applicant.FirstName, Applicant.Surname, 
    CASE WHEN COUNT(Employer.ID) = 1 
        THEN CAST(MIN(Employer.Id) AS varchar(10))
        ELSE 'Multiple Applications' 
    END AS Employer
FROM Applicant
    INNER JOIN Employer ON Applicant.Id = Employer.Id
GROUP BY Applicant.Id, Applicant.FirstName, Applicant.Surname

Upvotes: 2

Related Questions