MySQL group by for missing values - mysql

Given a table with the following data
ID Value
1 A
1 B
1 C
1 D
2 A
2 C
3 A
I would like to build a query that returns which values are missing from the id set based on value A being present. It can be assumed an ID for 'A' is always present.
Result:
ID | B | C | D
2 | 0 | 1 | 0
3 | 0 | 0 | 0
The values are A, B, C, D. In this example all values are there for ID 1 but the table reports that B is missing for both given that A is a value for ID 2 and so on.
I have a query to return which ID's are missing for a given value but I have not found a way to join all three together:
select id
from table_1
where id not in (
select id
from table_1
where value = 'B' #additional queries replacing 'B' with 'C' and 'D'
) and value = 'A'
order by id asc
Is it possible to combine those three separate queries in to a result table as I have laid out? I feel like this requires inner joins but have not been able to build out a query that works.

You could use conditional aggregation:
SELECT id,
SUM(Value = 'A') AS a,
SUM(Value = 'B') AS b,
SUM(Value = 'C') AS c,
SUM(Value = 'D') AS d
FROM tab
GROUP BY id;
DBFiddle Demo
Values list (A,B,C,D) has to be known in advance.
Skipping row if all values are present:
SELECT *
FROM (
SELECT id, SUM(Value = 'A') AS a,
SUM(Value = 'B') AS b,
SUM(Value = 'C') AS c,
SUM(Value = 'D') AS d
FROM tab
GROUP BY id
) sub
WHERE NOT (a>0 and b>0 and c>0 and d>0);
DBFiddle Demo2

Related

MySQL query for selecting distinct rows with all possible values in a column

Here's my DB table named 'test_tbl':
id
type
1
A
1
B
1
C
1
D
2
A
2
B
2
C
2
D
3
A
3
B
4
A
4
D
Here every 'id' can have at most 4 possible values (A,B,C,D) for 'type' column. I want to find out those ids who don't have all four values in 'type' column. So my expected output should be ids (3,4). I have tried as following:
select DISTINCT id
from test_tbl
where id NOT IN
(SELECT id FROM test_tbl
where
type='A' and type='B' and type='C' and type='D');
But this is giving output all the ids from table.
Use aggregation:
select id
from test_tbl
group by id
having count(distinct type) <> 4;
If you can have types other than A, B, C, and D, then add:
where type in ('A', 'B', 'C', 'D')

How to get count of each value against unique id in Mysql

I Have below mentioned table:
Where Val column has 3 distinct value a,b & c.
ID Val
1 a
1 a
1 b
2 b
2 c
2 c
3 c
I want to get count of unique ids and count of ids for respective Val value (i.e a,b & c).
I am using query like this but it helps me to identify count for a single Val value at a time.
SELECT ID,COUNT(*)
FROM table1
WHERE Val='c' GROUP BY ID;
Required output:
ID count a b c
1 3 2 1 0
2 3 0 1 2
3 1 0 0 1
You can use group by and sum the count when val is equal to a,b or c. See below:
select id,
count(*) as `count`,
sum(case when val = 'a' then 1 else 0 end) as a,
sum(case when val = 'b' then 1 else 0 end) as b,
sum(case when val = 'c' then 1 else 0 end) as c
from yourTable
group by id;
Just use conditional aggregation:
select id, count(*), sum(val = 'a') as a, sum(val = 'b') as b, sum(val = 'c') as c
from table1
group by id;

MySQL Count distinct values from one column

I have a table having three columns:
A B C
1 2 2
2 2 2
3 1 1
4 1 2
I want the count of those values which have C equal to 2 but with distinct values of B
So in this case for C = 2, count = 2 (B=2 and B=1)
I used the following command:
Select count(*) from mytable where C=2 group by (B)
but it yields:
count(*)
3
I have tried using "distinct" but it can't be use to select from one column
Have you tried
SELECT COUNT(DISTINCT B) FROM mytable WHERE C = 2;
Use sub query like this:
Select count(*) from (
select distinct B where c=2
)

Modify the values obtained through group_concat() in mysql

I have the following [table a]
id result
1 a
1 b
1 b
1 c
2 e
2 e
2 e
2 f
I'm getting the following after doing a group_concat
select id , Group_Concat(result) from [table a]
group by id
id result
1 a,b,b,c
2 e,e,e,f
BUT i want to display the no of times a value occurs before the value in the result set to avoid redundancy like the following
id result
1 a,2 b,c
2 3 e,f
How can I achieve it ?
Group by ID and result first to get the count. Then group by ID to build your strings.
select
id,
group_concat(case when cnt = 1 then result else concat(cnt, ' ', result) end) as results
from
(
select id, result, count(*)
from mytable
group by id, result
) t
group by id;

SQL Filtering group data

i've got a DB like this
id name group
with data like this
1 john A
2 john B
3 charles B
4 peter B
5 rose B
6 charles A
7 justin C
As you can see, the posibilities are that one ID it's associated with one group, or more than one group
i need a query for filtering
a) are in group A and B
b) are in group A but not B
c) are only in group A
a. select distinct name from tablename where group = 'A' or group = 'B';
b. select distinct name from tablename where group = 'A' and group <> 'B';
c. select distinct name from tablename where group = 'A' and
group not in (select distinct(t1.group) from tablename t1
where t1.group <> 'A');
I like approaching these problems using group by and the having clause. For your first question:
select name
from table
group by name
having sum(group = 'A') > 1 and sum(group = 'B') > 0;
The other two are:
having sum(group = 'A') > 1 and sum(group = 'B') = 0;
having sum(group = 'A') > 1 and sum(group <> 'A') = 0;