0

For presentation purposes I modify the table names and fields and simplify the SQL problem:

We have a table named A with only 2 columns:

Name   ServiceReceived
=========================
Mr A   Medical
Mr A   Dental
Mr A   HealthCare
Mr A   Special1
Mr B   Dental
Mr B   HealthCare
Mr C   Medical
Mr C   Dental
Mr C   HealthCare
Mr C   Special
Mr C   Special2 

I need a list of all people who revised medical or dental.

And ALSO received one or two of Special1 and Special2

I tried

where ServiceReceived in ('medical', 'dental')
  and ServiceReceived in ('Special1', 'Special2')

But this does not work.

======================================

Expected Results:(As you see MrB is not there, since he does not have Special1 or Special2

 Name   ServiceReceived
    =========================
    Mr A   Medical
    Mr A   Dental
    Mr A   HealthCare
    Mr A   Special1 
    Mr C   Medical
    Mr C   Dental
    Mr C   HealthCare
    Mr C   Special
    Mr C   Special2 
3
  • 1
    Specify the expected result as well. Commented Sep 1, 2020 at 20:33
  • 1
    Please read this for some tips on improving your question. Commented Sep 1, 2020 at 20:34
  • @jarlh I will further explain the expected results in question. Thanks Commented Sep 1, 2020 at 21:23

4 Answers 4

2

You can use aggregation and a having clause:

    select t.*
    from t
    group by Name
    having sum(case when ServiceRecived in ('Medical', 'Dental') then 1 else 0 end) > 0 and
           sum(case when ServiceRecived in ('Special1', 'Special2') then 1 else 0 end) between 1 and 2;

If you want to see all the details, you can use join, in or exists:

    select t.*
    from t
    where t.name in (select Name
                     from t
                     group by Name
                     having sum(case when ServiceRecived in ('Medical', 'Dental') then 1 else 0 end) > 0 and
                            sum(case when ServiceRecived in ('Special1', 'Special2') then 1 else 0 end) between 1 and 2
                    );
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I fit this into my actual SQL and will let you know!
Your SQL correctly eliminate MrB. But only give me result as MRA and MrB.I want also to see All of their service names.
That's it! My real SQL code is far very complex. but your solution applies to that also.
1


Select Name 
from 
(
Select Name,
       Sum(Case when ServiceRequested = 'Medical' then 1 else 0 end) as Medical,
       Sum(Case when ServiceRequested = 'Dental' then 1 else 0 end) as Dental,
       Sum(Case when ServiceRequested IN ('Special1','Special2') then 1 else 0 end) as Specials
from [dbo].[Services]
Group by Name
)s
Where  ( Medical >= 1 or Dental >= 1 ) AND Specials >= 1

Comments

0

The Following solution works with the SQL server INTERSECT table operator.

SELECT NAME 
FROM T 
WHERE ServiceReceived IN ('medical', 'dental') 
INTERSECT 
SELECT NAME 
FROM T WHERE 
ServiceReceived IN ('Special1', 'Special2')

Comments

-1

This should work.

SELECT NAME
FROM A
WHERE
    NAME IN (SELECT NAME FROM A AS A2 WHERE A2.ServiceReceived IN ('medical', 'dental'))
    AND NAME IN (SELECT NAME FROM A AS A2 WHERE A2.ServiceReceived IN ('Special1', 'Special2'))

4 Comments

What is A Here? if you are referring to TableA, your query still does even run.
What is 'SELECT NAME FROM A AS A2 WHERE A2.ServiceReceive' ????this SQL is not correct.
@SNash, I revised Chaim`s answer trying to make it clearer.
@SNash, The query works perfectly fine. Only Mr A and Mr C are pulling in the result set. If you want to see distinct values just add a DISTINCT clause. And 'A' is the table name, just like it is described in the question "We have a table named A"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.