Here my table:
id | marital_stat |
====================
1 divorced
2 divorced
3 married
4 single
I want to seperate the sums of each marital status, I'm using condition because in my tables using varchar not integer.
Here is my queries in my Model file:
SELECT
COUNT(CASE WHEN marital = 'divorced' THEN 1 END) AS divorcestat,
COUNT(CASE WHEN marital = 'married' THEN 1 END) AS marriedstat,
COUNT(CASE WHEN marital = 'single' THEN 1 END) AS singlestat
FROM status_tbl
With the query above produces the value that I want, the results was:
divorcestat | marriedstat | singlestat
--------------------------------------------
2 1 1
But now I need to add up all the values above and will produce as a Total, (divorcestat+marriedstat+singlestat) -> Total from the Count functions. How do I do that?I've tried some answer in stackoverflow but nothing worked. Group by, Union, just not working.
You can use count(*)
SELECT
COUNT(CASE WHEN marital = 'divorced' THEN 1 END) AS divorcestat,
COUNT(CASE WHEN marital = 'married' THEN 1 END) AS marriedstat,
COUNT(CASE WHEN marital = 'single' THEN 1 END) AS singlestat,
COUNT(*) AS Total
FROM status_tbl
You can add count(*) to the query
SELECT
COUNT(CASE WHEN marital = 'divorced' THEN 1 END) AS divorcestat,
COUNT(CASE WHEN marital = 'married' THEN 1 END) AS marriedstat,
COUNT(CASE WHEN marital = 'single' THEN 1 END) AS singlestat,
COUNT(*) AS total_stat
FROM status_tbl;
I hope that helps you.
You can also use a "table expression" to reuse the values you have already computed.
For example:
select
*,
divorcestat + marriedstat + singlestat as total
from (
SELECT
COUNT(CASE WHEN marital = 'divorced' THEN 1 END) AS divorcestat,
COUNT(CASE WHEN marital = 'married' THEN 1 END) AS marriedstat,
COUNT(CASE WHEN marital = 'single' THEN 1 END) AS singlestat
FROM status_tbl
) x
This can come in handy when the expression you use to compute values are complex and you don't want to repeat them in your query.
Related
Hi everyone I have this table and I want to show result in single row group by client id and show availability for stock 1 and 2.
Here is my table
id client stock material quantity availability date
62 56 1 0 0 100 2017-12-16 23:55:01
63 56 2 0 0 900 2017-12-16 23:55:01
64 56 1 100 -20 80 2017-12-16 23:55:20
65 56 1 80 100 180 2017-12-16 23:56:06
66 56 1 180 200 380 2017-12-16 23:56:21
67 56 1 380 500 880 2017-12-16 23:58:11
68 56 1 880 -580 300 2017-12-16 23:58:38
69 56 2 900 -90 810 2017-12-17 23:59:18
Outcome I want is get result from last date, group by client id and combine stock 1 and stock 2 to single row
client availability1 availability2
56 300 810
I try this query
SELECT
historys.id
,(CASE WHEN historys.stock = 1 THEN availability END) AS availability1
,(CASE WHEN historys.stock = 2 THEN availability END) AS availability2
FROM historys
GROUP BY historys.client
ORDER by historys.id
The result is
id availability1 availability2
56 NULL 810
I will be grateful if someone help me. Thanks.
You need to filter to the right rows before the aggregation. Here is one method:
SELECT h.client,
MAX(CASE WHEN h.stock = 1 THEN h.availability END) AS availability1
MAX(CASE WHEN h.stock = 2 THEN h.availability END) AS availability2
FROM historys h
WHERE h.date = (SELECT MAX(h2.date) FROM historys h2 WHERE h2.stock = h.stock)
GROUP BY h.client
Use a union
SELECT
client, max(availability1) AS availability1, max(availability2) AS availability2
FROM
(
SELECT
client
,availability AS availability1
,0 AS availability2
FROM historys hist
WHERE id = (select max(id) from historys where client = hist.client and stock = 1)
UNION ALL
SELECT
client
,0 AS availability1
,availability AS availability2
FROM historys hist2
WHERE id = (select max(id) from historys where client = hist2.client and stock = 2)
) a
GROUP by client
ORDER by client
The NULL you have is because your selecting data from lines of historys that cannot contain the availability for stock = 1 and stock = 2 at the same time.
You can bypass that using historys both times like above :
In the subrequest (as d) we get max dates by client, then we join history two times to get both availability in a row.
select d.client,
h1.availability availability1,
h2.availability availability2
from
(
select client,
max(case when stock = 1 then date end) d1,
max(case when stock = 2 then date end) d2
from historys
group by client
) d
join historys h1 on (h1.stock = 1
and h1.date = d.d1
and h1.client = d.client)
join historys h2 on (h2.stock = 2
and h2.date = d.d2
and h2.client = d.client)
You can find an SQLFiddle here : http://sqlfiddle.com/#!9/d1ea4/5
Thanks
This may help you :
SELECT T.client client ,
SUM(CASE WHEN T.Stock = 1 THEN T.availability
END) availability1 ,
SUM(CASE WHEN T.Stock = 2 THEN T.availability
END) availability2
FROM historys T
INNER JOIN ( SELECT MAX(date) Max_Date ,
stock
FROM historys
GROUP BY stock
) T1 ON T1.Max_Date = T.date
AND T1.stock = T.stock
GROUP BY T.client
Depending on your MySQL version, you should be able to do this with a window function & a common table expression:
-- Build derived src table with "latest date" rows
WITH src AS (
SELECT id, client, stock, material, quantity, availability, date
FROM (
SELECT
id, client, stock, material, quantity, availability, date,
ROW_NUMBER() OVER(PARTITION BY client, stock ORDER BY date DESC) ClientStockRank -- For each (client, stock) pair, rank each row by date
FROM historys a
) src
WHERE ClientStockRank = 1 -- Only get rows with "latest date"
)
SELECT
client,
MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) END AS Availability1, -- Get "max" value for "stock 1"
MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) END AS Availability2 -- Get "max" value for "stock 2"
FROM src
GROUP BY client
I think you need MySQL 8+. If not, there should be other ways to do it too. Let me know if that works.
Update
Actually, this should also suffice:
SELECT DISTINCT
client,
MAX(CASE WHEN stock = 1 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS Availability1,
MAX(CASE WHEN stock = 2 THEN availability ELSE NULL) OVER(PARTITION BY client ORDER BY date DESC) AS availability2
FROM historys
Can't manage to come up with a correct query to compute the total no of students
I have three tables:
student - contains student profile either male or female
2.student_attendance - contains attendance details for whether a student was present a either "0" or "1"
attendance - contains all session details where by a one session can be attended by a number of students.
I need to calculate the number of boys/girls in present or absent for a session.
my major headache is to interpreate these logic to sql
if(in_attendace =1) then
sum the number of boys as boys_present
sum the number of girls as girls_present
else
sum the number of boys as boys_absent
sum the number of girls as girls_absent
# MY closest sql is its not working :(
select
case when a.in_attendance = 1 then
SUM(CASE b.gender when 1 then 1 else 0 end ) as male_present,
SUM(CASE b.gender when 2 then 1 else 0 end ) as female_present,
ELSE
SUM(CASE b.gender when 1 then 1 else 0 end ) as male_absent,
SUM(CASE b.gender when 2 then 1 else 0 end ) as female_absent
END
from attendance_student as a inner join student as b on a.student_id = b.id where a.session_details_id = 38
Well, you are not very far from the solution, you just need to separate them into different columns(I assume that's what you want) :
select COUNT(CASE WHEN a.in_attendance = 1 and b.gender = 1 then 1 END) as male_present,
COUNT(CASE WHEN a.in_attendance = 1 and b.gender = 2 then 1 END) as female_present,
COUNT(CASE WHEN a.in_attendance = 0 and b.gender = 1 then 1 END) as male_absent,
COUNT(CASE WHEN a.in_attendance = 0 and b.gender = 2 then 1 END) as female_absent
FROM attendance_student a
INNER JOIN student b
ON a.student_id = b.id
WHERE a.session_details_id = 38
StudentID | SubCode | SubName
-------------------------------
1 1 Math
1 2 Science
1 3 English
2 1 Math
2 2 Science
3 2 Science
4 1 Math
4 3 English
This is my subject table.
How can I find students who have registered as following
Students who have registered in only Maths NOT in English and Science
Students who have registered In Maths And English NOT Science
Students who have registered In Science And Maths And English
in a single SQL query.
I tried as this way
SELECT DISTINCT
`stud_id` FROM `subj_assign`
WHERE
`subj_id` = '1,2'
AND STATUS = '1'
ORDER BY
`subj_assign`.`stud_id` ASC
AND Also This way tried but Not Working
SELECT stud_id FROM subj_assign GROUP BY stud_id
HAVING Count(CASE WHEN subj_id = '1' AND
status='1' THEN 1 END) = 1 AND
Count(CASE WHEN `subj_id` = '2' AND
status='1' THEN 1 END) = 1
its rum for me. may be its help for you also.
SELECT stud_id FROM subj_assign GROUP BY stud_id
HAVING Count(CASE WHEN subj_id = '1' AND
status='1' THEN 1 END) = 1 AND
Count(CASE WHEN `subj_id` = '2' AND
status='1' THEN 1 END) = 1
then compare with total subject of student and filtered subjects with condition
Try this:-
SELECT
(SELECT DISTINCT StudentID FROM subject WHERE SubName = 'Math' AND StudentID NOT IN ( SELECT DISTINCT StudentID FROM subject WHERE SubName IN ('English', 'Science')) AS STUD_ONLY_IN_MATHS,
(SELECT DISTINCT StudentID FROM subject WHERE SubName in ('Math', 'English') AND StudentID NOT IN ( SELECT DISTINCT StudentID FROM subject WHERE SubName IN ('Science')) AS STUD_IN_MATHS_AND_ENGLISH,
(SELECT DISTINCT StudentID FROM subject WHERE SubName in ('Math', 'English', 'Science') AS STUD_IN_MATHS_ENGLISH_SCIENCE);
You can join the table with the table itself grouped by StudentID. That way you'll be able to test the number of rows and the SubCode at the same time.
SELECT DISTINCT tmp.StudentID
FROM subj_assign tmp JOIN (SELECT StudentID, COUNT(*) as total
FROM subj_assign
GROUP BY StudentID) tmpG on tmp.StudentID = tmpG.StudentID
WHERE (tmp.SubCode = 1 and total = 1) --Only Math
OR (total = 2 and SubCode != 2) --No Science
OR total = 3 --Math, English, Science
I have searched high an low for a solution, but I just can't get my head wrapped around how to set this up.
I have a table called "cals". It contains a column called "rep_code". Which contains a certain value identifying the cal, ie. "EFM","LM" etc. The "cals" list of records are linked to wells by "well_id" which is the indexer on another table called "wells". Now each record in the wells table is linked by "run_id" which is the indexer on another table called "runs".
Wells table:
Indexer | run_id
1 | 5
2 | 3
3 | 5
4 | 2
cals table:
Indexer | well_id | rep_code
1 | 3 | LM
2 | 4 | EFM
3 | 1 | LM
4 | 3 | EFM
Now when I view the list of runs, I want to display the total number reports in the run that have "EFM" under "rep_code", and total number of "LM" codes etc. So on the list of runs, the run with ID of 5 should say total of 2 "LM" reports and 1 "EFM". Run number 2 should just have 1 "EFM and 0 "LM"
Basically, what I think I need to do is " Join wells into cals adding run_id where well_id = $well_id from run list"...I think, every time I read this I get a little confused. I am new to "join" so I apologize.
I have managed to put together this bit of code to count each occurrence which works for one well, but cannot seem to get my head wrapped around putting it all into a functional statement for all wells in the run.
$sql = "SELECT
COUNT(CASE WHEN rep_code='LM' THEN 1 END) AS LM_tot,
COUNT(CASE WHEN rep_code='EFM' THEN 1 END) AS EFM_tot,
COUNT(CASE WHEN rep_code='GM' THEN 1 END) AS GM_tot
FROM cals WHERE well_id = '$well_id'";
$query = #mysql_query($sql);
$result = #mysql_fetch_array($query);
$LM_tot = $result['LM_tot'];
$EFM_tot = $result['EFM_tot'];
$GM_tot = $result['GM_tot'];
I also started this join, but I haven't gotten it to work yet.
sql = "SELECT
COUNT(CASE WHEN rep_code='LM' THEN 1 END) AS LM_tot,
COUNT(CASE WHEN rep_code='EFM' THEN 1 END) AS EFM_tot,
COUNT(CASE WHEN rep_code='GM' THEN 1 END) AS GM_tot
FROM cals, wells INNER JOIN wells ON cals.well_id = wells.indexer
WHERE run_id = '$run_id'";
I hope I have explained this clear enough.
Putting apart the join you are talking to put your query to work you just need to change a bit:
$sql = "SELECT
SUM(CASE WHEN rep_code='LM' THEN 1 ELSE 0 END) AS LM_tot,
SUM(CASE WHEN rep_code='EFM' THEN 1 ELSE 0 END) AS EFM_tot,
SUM(CASE WHEN rep_code='GM' THEN 1 ELSE 0 END) AS GM_tot
FROM cals
INNER JOIN
wells ON cals.well_id = wells.indexer
WHERE cals.well_id = '$well_id'";
If there more things to add, update your question with your tables structure and put some example data and the desired result, then I will update my answer.
This is what i ended up using, and works great.
$sql = "SELECT
COUNT(CASE WHEN rep_code='LM' THEN 1 END) AS LM_tot,
COUNT(CASE WHEN rep_code='EFM' THEN 1 END) AS EFM_tot,
COUNT(CASE WHEN rep_code='GM' THEN 1 END) AS GM_tot
FROM cals
INNER JOIN
wells ON cals.well_id = wells.indexer
WHERE run_id = '$run_id'";
I require 3 different counts on single column for different conditions.
Table structure:
interview-
id-int(10)
c_id-int(10)
experience-varchar2(100)
experience have 3 different values-
1)positive
2)negative
3)neutral
I require 3 different counts of "count_positive", "count_negative" and "count_neutral" for where condition of c_id=10.
I know it can get by 3 different queries. Can I able to get 3 counts by single query?
SELECT
SUM(CASE experience
WHEN 'positive' THEN 1
ELSE 0
END) AS CountPositive
, SUM(CASE experience
WHEN 'negative' THEN 1
ELSE 0
END) AS CountNegative
, SUM(CASE experience
WHEN 'neutral' THEN 1
ELSE 0
END) AS CountNeutral
FROM Interview
WHERE c_id = 10
select 'Positive Count' , count(*)
from interview
where experience = 'positive'
UNION
select 'Negative Count' , count(*)
from interview
where experience = 'negative'
UNION
select 'Neutral' , count(*)
from interview
where experience = 'neutral'
This is the modified version of Adam Wenger answer:
SELECT
COUNT(CASE experience
WHEN 'positive' THEN 1
ELSE NULL
END) AS CountPositive
, COUNT(CASE experience
WHEN 'negative' THEN 1
ELSE NULL
END) AS CountNegative
, COUNT(CASE experience
WHEN 'neutral' THEN 1
ELSE NULL
END) AS CountNeutral
FROM Interview
WHERE c_id = 10
I think this works fine:
select 'count of ' + experience,
count(experience)
from interview
where c_id=10
group by experience
I got solution for active record query in Codeigniter:
$this->db->select('SUM(CASE experience
WHEN "positive" THEN 1
ELSE 0
END) AS CountPositive
, SUM(CASE experience
WHEN "negative" THEN 1
ELSE 0
END) AS CountNegative
, SUM(CASE experience
WHEN "neutral" THEN 1
ELSE 0
END) AS CountNeutral');
$this->db->where('c_id',10);
$query=$this->db->get('interview');
$result=$query->result();
$interview_experience=$result[0];
$positive_count=$interview_experience->CountPositive;
$negative_count=$interview_experience->CountNegative;
$neutral_count=$interview_experience->CountNeutral;