I have data in database like this
id class gender
1 A F
2 B F
3 A M
4 A F
5 A M
6 B M
7 A F
From this data I want to make select statement to produce report like this
_________________________
Gender
class M F Total
_________________________
A 2 3 5
B 1 1 2
_________________________
TOTAL 3 4 7
How can I make that select statement ?
Have a look at the following example
SQL Fiddle DEMO
SELECT class,
SUM(CASE WHEN gender = 'M' THEN 1 ELSE 0 END) `M`,
SUM(CASE WHEN gender = 'F' THEN 1 ELSE 0 END) `F`,
COUNT(1) Total
FROM Table1
GROUP BY class
To get totals for each gender:
SELECT class, gender, COUNT(*) as gender_count
FROM Gender
GROUP BY class, gender;
To get total:
SELECT class, COUNT(*) as total_count
FROM Gender
GROUP BY class;
Related
I have join query which is not returning the result as expected. Below is the table structure, query used, result and expected result
Table A:
Id Name Token
1 A abcdef
2 B think
3. C Bxjscmsdnj
Table B:
id TableA_id configKey configValue
1 2 pmt ins
2 2 vat gas
3 1 vat nnnb
4 1 pmt mc
5 3 vat nhu
6 3 pmt nnu
7 2 hit bxhsjab
Below is the query that I used:
SELECT A.Token,
A.Name,
CASE
WHEN B.configKey = 'pmt’ THEN B.configValue
ELSE ''
END AS ‘PMT’,
CASE
WHEN B.configKey = ‘vat’ THEN B.configValue
ELSE ''
END AS ‘VAT’
FROM TABLEA A
INNER JOIN TABLEB B ON A.Id = B.TableA_id
WHERE B.configKey IN (‘PMT’, ‘VAT’)
ORDER BY A.id DESC;
Result:
Token Name PMT VAT
1 A nnnb
1 A mc
2 B gas
2 B ins
Expected Result:
Token Name PMT VAT
1 A mc nnnb
2 B ins gas
You want conditional aggregation. First, add a group by clause that groups together rows having the same id and name; then, wrap the case expressions in an aggregate function such as max():
select
a.id,
a.name,
max(case when b.configkey = 'pmt' then b.configvalue end) pmt,
max(case when b.configkey = 'vat' then b.configvalue end) vat
from tablea a
inner join tableb b on a.id = b.tablea_id
where b.configkey in ('pmt', 'vat')
group by a.id, a.name
order by a.id desc;
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;
I have a table where I can store the same name with different states.
|ID|name|state
1 A 1
2 A 2
3 B 3
4 C 1
There 3 states 1,2,3.
How can I find those records which has no state 3, maximum 2?
In this example A and C has no state 3 so they would be the result of the query:
SELECT * FROM `records` WHERE (`state_id`!=3)
It only returns rows without state 3 but it can be that value.
http://www.sqlfiddle.com/#!9/35dbe/2
SELECT r.*
FROM `records` r
LEFT JOIN `records` r3
ON r.name = r3.name
AND r3.state=3
WHERE r3.state IS NULL
How about a DISTINCT and NOT IN?
Something like
SELECT DISTINCT Name
FROM Table1 t
WHERE Name NOT IN (
SELECT Name
FROM Table1 s
WHERE s.State = 3)
SQL Fiddle DEMO
You can do this with conditional aggregation:
select name from t
group by name
having sum(case when state = 3 then 1 else 0 end) = 0
Fiddle http://sqlfiddle.com/#!9/a8bb5/2
Complaint_status Table : multiple rows for a complaints
id complaint_id status_type status_value
1 11 2 0
2 11 2 2
3 11 2 1
4 11 2 2
Trying to get min(id) having status_type=2 and status_value=2 but showing null,have to use case statement for doing other stuff.
SELECT c3.id AS Ticket_id,
CASE
WHEN cs.status_value=2 THEN cs.created_at
ELSE NULL
END AS Closure_date
FROM complaint c3
INNER JOIN complaint_status cs ON cs.complaint_id=c3.id
WHERE cs.id IN
(SELECT min(id)
FROM complaint3_status
WHERE complaint_id=c3.id
AND status_type=2)
AND c3.id IN(11)
Here is one method that gives you the entire row:
select cs.*
from complaint_status cs
where status_type = 2 and status_value = 2
order by id asc
limit 1;
You can just use select id if that is all you want. I have no idea what case has to do with this query.
t_no name value
1 a 45
1 b 23
1 c 5
1 a 12
1 b 99
1 c 6
I need to show my above table as
no name value1 value2
1 a 45 12
1 b 23 99
1 c 5 6
You can't create dynamic columns in mysql alone, either in scripting language, or you can use group_concat to have them in one column:
SELECT to_no, name, GROUP_CONCAT(value)
FROM table GROUP BY to_no, name
result:
no name value
1 a 45,12
1 b 23,99
1 c 5,6
MySQL does not have a pivot function, but you can use an aggregate function with a CASE expression. Since you have multiple values for each t_no and name, then you could use user defined variables to assign a row number to each group of values:
select t_no, name,
max(case when rn=1 then value end) value1,
max(case when rn=2 then value end) value2
from
(
select t_no, name, value,
#rn:=case when #prev=t_no and #c=name then #rn else 0 end +1 rn,
#prev:=t_no,
#c:=name
from yourtable
cross join (select #rn:=0, #prev:=0, #c:=null) c
order by t_no, name
) d
group by t_no, name
order by t_no, name;
See SQL Fiddle with Demo