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;
Related
The original table is large so I will simplify it:
mytable:
CONDITION SIZE
1 10
9 10
9 10
1 20
9 20
1 20
1 30
With a query similar to
SELECT
CASE WHEN CONDITION=1 THEN 'OK' ELSE 'BAD' END AS Status,
SUM (CASE WHEN SIZE=10 THEN 1 ELSE 0 END) AS Small,
SUM (CASE WHEN SIZE=20 THEN 1 ELSE 0 END) AS Medium,
SUM (CASE WHEN SIZE=30 THEN 1 ELSE 0 END) AS Large,
FROM mytable GROUP BY Status
Then we have this result
Status Small Medium Large
OK 1 2 1
BAD 2 1 0
What is the proper code to get:
Status Small Medium Large
OK 1 2 1
BAD 2 1 0
TOTAL 3 3 1
You can add a WITH ROLLUP clause to your GROUP BY condition like this:
SELECT
CASE WHEN CONDITION=1 THEN 'OK' ELSE 'BAD' END AS Status,
SUM (CASE WHEN SIZE=10 THEN 1 ELSE 0 END) AS Small,
SUM (CASE WHEN SIZE=20 THEN 1 ELSE 0 END) AS Medium,
SUM (CASE WHEN SIZE=30 THEN 1 ELSE 0 END) AS Large,
FROM mytable
GROUP BY Status WITH ROLLUP
This would yield a result set like:
Status Small Medium Large
OK 1 2 1
BAD 2 1 0
[NULL] 3 3 1
You would need to understand the behavior that there would not be any Total value in the Status column. Instead the Status column would have a NULL value indicating that this is where the rollup is made.
For more information you can read the documentation here: http://dev.mysql.com/doc/refman/5.6/en/group-by-modifiers.html
If I understand correctly you need union in a total query since you cannot aggregate in different ways at the same time.
SELECT
CASE WHEN CONDITION=1 THEN 'OK' ELSE 'BAD' END AS Status,
SUM (CASE WHEN SIZE=10 THEN 1 ELSE 0 END) AS Small,
SUM (CASE WHEN SIZE=20 THEN 1 ELSE 0 END) AS Medium,
SUM (CASE WHEN SIZE=30 THEN 1 ELSE 0 END) AS Large,
FROM mytable GROUP BY Status
UNION
SELECT
'Total' AS Status,
SUM (CASE WHEN SIZE=10 THEN 1 ELSE 0 END) AS Small,
SUM (CASE WHEN SIZE=20 THEN 1 ELSE 0 END) AS Medium,
SUM (CASE WHEN SIZE=30 THEN 1 ELSE 0 END) AS Large,
FROM mytable
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.
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
I have a table like this. Now i want two sum(hour).. 1 for place_type '1' and another for place_type '2'. Is it possible in mysql?
Now my query is
SELECT sum(hour) as totalHour from category_data group by category_data.user_id
also tried with IF condition but not working
SELECT IF(place_type='1',sum(hour),0) home,
IF(place_type='2', sum(hour), 0) center,
from category_data group by category_data.user_id
user_id place_type hour
1 1 2
1 2 5
2 1 3
2 2 4
3 1 2
Thanks in advance
Conditional aggregation is what you need here.
select sum(case when place_type = 1 then `hour` end),
sum(case when place_type = 2 then `hour` end)
from category_data
Example fiddle
I have a table named watersourcetype consisting of water types.
link : watersourcetype TABLE
and another table health_and_sanitation consisting of household no. and watersource_id
I have this query :
SELECT h.purok_number,
SUM(CASE WHEN hs.watersystem = 'Community water system-own' THEN 1 ELSE 0 END) AS a,
SUM(CASE WHEN hs.watersystem = 'Community water system-shared' THEN 1 ELSE 0 END) AS b,
SUM(CASE WHEN hs.watersystem = 'Deep well-own' THEN 1 ELSE 0 END) AS c,
SUM(CASE WHEN hs.watersystem = 'Deep well-shared' THEN 1 ELSE 0 END) AS d,
SUM(CASE WHEN hs.watersystem = 'Artesian well-own' THEN 1 ELSE 0 END) AS e,
SUM(CASE WHEN hs.watersystem = 'Artesian well-shared' THEN 1 ELSE 0 END) AS f,
SUM(CASE WHEN hs.watersystem = 'Dug/shallow well-own' THEN 1 ELSE 0 END) AS g,
SUM(CASE WHEN hs.watersystem = 'Dug/shallow well-shared' THEN 1 ELSE 0 END) AS h,
SUM(CASE WHEN hs.watersystem = 'River, stream, lake, spring, bodies of water' THEN 1 ELSE 0 END) AS i,
SUM(CASE WHEN hs.watersystem = 'Bottled water' THEN 1 ELSE 0 END) AS j,
SUM(CASE WHEN hs.watersystem = 'Tanker truck/Peddler' THEN 1 ELSE 0 END) AS k
FROM health_and_sanitation AS hs, house_hold AS h, f_member as f
WHERE
h.brgy_name='$brgy_name' AND
h.hh_number=hs.hh_number AND
h.hh_number=f.hh_number AND
f.is_household='HOUSEHOLD' AND
EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year'
group by h.purok_number
order by h.purok_number
what i want is to put a for loop inside above sql query since table watersourcetype is dynamic another data will be added to watersourcetype soon so i dont have to define in my case statement on above query the watersystem . The query should look like this :
$qry = pg_query("select cwatertype from tbl_watersourcetype");
SQL:
SELECT h.purok_number,
// is this possible ? putting a while loop or forloop inside a query in PHP ?
while($row = pg_fetch_array($qry))
{
SUM(CASE WHEN hs.watersystem = '$row['cwatertype']' THEN 1 ELSE 0 END) AS a
}
FROM health_and_sanitation AS hs, house_hold AS h, f_member as f
WHERE
h.brgy_name='$brgy_name' AND
h.hh_number=hs.hh_number AND
h.hh_number=f.hh_number AND
f.is_household='HOUSEHOLD' AND
EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year'
group by h.purok_number
order by h.purok_number
is that possible ?
If I understand your query correctly, you are trying to retrieve the number of watersourcetypes per household, with a single record returned per household. If that is indeed the case you need to use the crosstab() function from the tablefunc extension.
However, if you can get by with multiple rows giving the number of sources per watersourcetype per household then you can simply and more efficiently use the COUNT() aggregate in the SELECT statement (with some decent formatting for legibility):
SELECT h.purok_number, hs.watersystem, COUNT(hs.watersystem) AS num
FROM health_and_sanitation AS hs,
house_hold AS h,
f_member AS f
WHERE h.brgy_name='$brgy_name'
AND h.hh_number=hs.hh_number
AND h.hh_number=f.hh_number
AND f.is_household='HOUSEHOLD'
AND EXTRACT(YEAR FROM f.reg_date) BETWEEN '$sel_year' AND '$sel_year'
GROUP BY h.purok_number, hs.watersystem
ORDER BY h.purok_number;
Additionally, I am assuming that your health_and_sanitation table is a view on the watersourcetype table; otherwise you are duplicating data in two tables which is (generally) a big boo-boo. Given also your issue with additional water source type, you may want to see if your database design is in 3NF.
Cheers,
Patrick
this is an example on how to put for loop inside SELECT statement :
$qry_6_12 .= " SELECT count(ncropfarmingreasonid) as counted , " ;
for($i=2;$i<=$count_row;$i++) // loop the number of rows and used $i as ncropfarmingreasonid
{
if(($count_row-$i)==0)
{
$qry_6_12 .= "SUM(CASE WHEN ncropfarmingreasonid = ".$i." THEN 1
ELSE 0 END) a".$i."";
}
else
{
$qry_6_12 .= "SUM(CASE WHEN ncropfarmingreasonid = ".$i." THEN 1
ELSE 0 END) a".$i.",";
}
}
$qry_6_12 .= " FROM tbl_climatechange as c, tbl_household as h, tbl_barangay as b where h.chholdnumber=c.chholdnumber and b.cbrgycode=h.cbrgycode and b.cbrgyname = 'AMPAYON' ";
$query_6_12 = pg_query($qry_6_12);