SQL : Extract distinct value - sql

I have a table with two col's
EmpID Beneifts
1 A
1 B
2 A
3 A
3 c
4 A
my expected output is just that empId with only benefits A
EmpID Benefits
2 A
4 A
please help me with a query.

Use NOT EXISTS to return a row of same EmpID doesn't have any benefit but 'A':
select *
from tablename t1
where t1.Benefits = 'A'
and not exists (select 1 from tablename t2
where t2.EmpID = t1.EmpID
and t2.Benefits <> 'A')
Or, do a GROUP BY:
select EmpID
from tablename
group by EmpID
having min(Benefits) = 'A'
and max(Benefits) = 'A'

Related

SQL DB2 Select filtering values with Same Id and several rows

my problem looks like this. I have a large table with 1M+ records.
It looks something like this
ID STEP_ID
1 abc
1 dce
1 bbv
2 abc
2 ddb
3 bbv
4 asd
The thing is I want to write select query that would exclude all IDs if step_id is equal to abc. So it would look like
ID STEP_ID
3 bbv
4 asd
You can use not exists:
select t.*
from mytable t
where not exists (select 1 from mytable t1 where t1.id = t.id and t1.step_id = 'abc')
For performance, consider an index on (id, step_id).
Use not exists:
select t.*
from t
where not exists (select 1 from t t2 where t2.id = t.id and t2.step_id = 'abc');
For performance, you want an index on (id, step_id) -- both columns, in that order.
If you cannot create an index, it might be faster to use window functions:
select t.*
from (select t.*,
sum(case when step_id = 'abc' then 1 else 0 end) over (partition by id) as num_abc
from t
) t
where num_abc = 0;

TSQL - Select rows with same column A but different column B

I'm trying to find rows (Name) that does not have ID = 1. For example, if my table looked like this:
Name ID
--------------
A 1
A 0
B 1
B 0
C 0
D 2
D 0
The answer to this query would be:
Name
-----
C
D
Do you have any idea?
SELECT Name
FROM myTable
GROUP BY Name
HAVING SUM(CASE WHEN ID = 1 THEN 1 ELSE 0 END) = 0
Here is one way to do it:
SELECT DISTINCT Name
FROM Table t0
WHERE NOT EXISTS
(
SELECT 1
FROM Table t1
WHERE t0.Name = t1.Name
AND t1.Id = 1
)
Try this query:
SELECT DISTINCT(name)
FROM tbl t1
WHERE
NOT EXISTS (SELECT name FROM tbl t2 WHERE ID=1 AND t1.name=t2.name)
Select Distinct name
From myTable
Where name not in (Select name From myTable Where id= 1)

How to get an ID associated with at least all contents?

Suppose we have the database:
-----------
| A -|- B |
|----|----|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
-----------
Where A and B is the primary key. Suppose we want to get all As that contain the elements in B of 1 and 2.
SELECT A FROM Table WHERE B = 1 AND B = 2;
The above fails because it never holds true as the query is only for a single record.
SELECT A FROM Table WHERE B = 1 OR B = 2;
Works but erroneously includes the primary key value 2, which only maps to 1 in B, and not both 1 and 2 in B.
GROUP BY solution, return all a's that have more than 1 different b value in (1,2):
select a from table
where b in (1,2)
group by a
having count(distinct b) > 1
Or, JOIN solution:
select distinct a
from (select a from table where b = 1) t1
join (select a from table where b = 2) t2
on t1.a = t2.a
Or an INTERSECT solution:
select a from table where b = 1
intersect
select a from table where b = 2
Edit:
GROUP BY query that perhaps is faster then the HAVING count distinct version:
select a from table
where b in (1,2)
group by a
having max(b) <> min(b)
You can use the group by method from jarlh or make a Join with a 'distinct':
select distinct a
from (select a from table where b = 1) t1
join (select a from table where b = 2) t2
on t1.a = t2.a
Something like this (assuming that you need to filter by the specific IDs in B.
SELECT DISTINCT A
FROM Table AS T
WHERE EXISTS (SELECT 1 from Table WHERE Table.A = T.A and B = 1)
AND EXISTS (SELECT 1 from Table WHERE Table.A = T.A and B = 2)
Try this
SELECT A
FROM Table
WHERE EXISTS (
SELECT 1
FROM Table t1
WHERE t1.A = Table.A
AND t1.B = 1
)
AND EXISTS (
SELECT 1
FROM Table t2
WHERE t2.A = Table.A
AND t2.B = 2
)
A cannot be the primary key here, since the column contains duplicates.
One possible solution:
SELECT * FROM (SELECT A, group_concat(B, ',') AS C FROM tab GROUP BY A) s WHERE s.C = "1,2";

Select Grouped Column Values Where Have Same Id In SQL Server

I have a table like this.
TABLE-1
id Code
-----------------
1 N188
1 N1Z2
1 N222
2 N189
2 N1Z2
2 N1Z3
3 N188
3 A123
3 B321
4 N188
4 A333
4 B444
I want to select id and code only code has N188.Result should like this:
TABLE-2
id Code
---------------
1 N188
1 N1Z2
1 N222
3 N188
3 A123
3 B321
4 N188
4 A333
4 B444
How can I write sql for this in SQL Server?
Thanks
You can use EXISTS for this:
SELECT id, code
FROM table1 t
WHERE EXISTS (
SELECT 1
FROM table1 t2
WHERE t.id = t2.id
AND t2.Code = 'N188'
)
Condensed SQL Fiddle Demo
Using INNER JOIN
SELECT *
FROM tablename A
JOIN (SELECT id
FROM tablename
WHERE code = 'N188') B
ON a.id = b.id
Here is an alternative method that uses window functions:
select id, code
from (select t.*,
sum(case when code = 'N188' then 1 else 0 end) over (partition by id) as cnt_n188
from table t
) t
where cnt_n188 > 0;

Union three tables and show where data came from

have no idea how to solve following:
There are three tables each with a column of names, for example
Table 1 - column name 'Name' - values 'A', 'B' and 'C'
Table 2 - column name 'Name' - values 'A' and 'B'
Table 3 - column nane 'Name' - values 'A' and 'C'
The goal is to UNION the tables - each value of the three tables should be shown only one time. In addition there should be three new "virtual columns" showing in which table the value is included('1' when value is included, '0' if not). So the result should look like this:
Value | Table1 | Table2 | Table3
--------------------------------
A | 1 | 1 | 1
B | 1 | 1 | 0
C | 1 | 0 | 1
Hope someone can help me, thanks in advance.
Does this do what you want?
select Name, max(Table1) as Table1, max(Table2) as Table2, max(Table3) as Table3
from (select Name, 1 as Table1, 0 as Table2, 0 as Table3
from table1
union all
select Name, 0 as Table1, 1 as Table2, 0 as Table3
from table2
union all
select Name, 0 as Table1, 0 as Table2, 1 as Table3
from table3
) t
group by Name;
You might want to use sum() instead of max() to get the number of times the value occurs in each table.
If your db supports full joins you can try the query below.
select
coalesce(t1.Name,t2.Name,t3.Name) myValue,
(case when max(t1.Name) is not null then 1 else 0 end) c1,
(case when max(t2.Name) is not null then 1 else 0 end) c2,
(case when max(t3.Name) is not null then 1 else 0 end) c3
from
Table1 t1
full join Table2 t2 on t1.Name = t2.Name
full join Table3 t3 on t1.Name = t3.Name
group by coalesce(t1.Name,t2.Name,t3.Name)
If you know that a value will not appear more than once in each table, you can remove the group by and max parts.
Here's my attempt (update: works f.e. in SQL-Server 2005 and upwards due to the CTE):
With names AS
(
SELECT Name, Source = 'T1'
FROM dbo.Table1
UNION ALL
SELECT Name, Source = 'T2'
FROM dbo.Table2
UNION ALL
SELECT Name, Source = 'T3'
FROM dbo.Table3
)
SELECT n.Name,
Table1 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T1' AND n2.Name=n.Name)
THEN 1 ELSE 0 END,
Table2 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T2' AND n2.Name=n.Name)
THEN 1 ELSE 0 END,
Table3 = CASE WHEN EXISTS
(SELECT 1 FROM names n2
WHERE Source = 'T3' AND n2.Name=n.Name)
THEN 1 ELSE 0 END
FROM names n
GROUP BY n.Name
Demo