#my code
select('a.client_location_id as location_id','b.name as location_name','c.name as client_name',
DB::raw('SUM(CASE WHEN a.type = 1 employee_qty THEN 1 ELSE 0 END) as e_qty_in'),
DB::raw('SUM(CASE WHEN a.type = 2 employee_qty THEN 1 ELSE 0 END) as e_qty_out')
)
i want to do IF conditioning like , if type = 1 result is SUM employee_qty AS e_qty_in and if type 2 the result is SUM employee_qty AS e_qty_out,
#table
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
I want to retrieve columns name from table whose value is 1
My query is give below...
mysqli_query($conn,"SELECT * FROM `tbl_therapist_schedule` WHERE `schedule_date`='30.11.2017'");
My table structure is give below...
slot1 slot2 slot3
1 1 0
2 1 1
1 1 2
3 1 0
my result...
slot1 slot2 slot3
I have the serious feeling that your data is not normalized. Instead of having separate columns for each slot, I would store all this data in a single column with metadata to relate each slot's state.
That being said, one way to get the output you want would be to aggregate over each slot column and check for the presence/absence of at least one 1 value. I then use GROUP_CONCAT to generate a CSV list of matching slots.
SELECT GROUP_CONCAT(slots)
FROM
(
SELECT
CASE WHEN SUM(CASE WHEN slot1 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot1' END AS slots
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
UNION ALL
SELECT
CASE WHEN SUM(CASE WHEN slot2 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot2' END
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
UNION ALL
SELECT
CASE WHEN SUM(CASE WHEN slot3 = 1 THEN 1 ELSE 0 END) > 0
THEN 'slot3' END
FROM tbl_therapist_schedule
WHERE schedule_date = '30.11.2017'
) t;
Demo
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 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);
Suppose I have a table:
col1, col2, col3
1 0 1.3
0 0 0
0 1 0
1 1.5 1
Now, let's say each row has a "weight" calculated as this:
(col1 > 0 ? 1 : 0) + (col2 > 0 ? 1 : 0) + (col3 > 0 ? 1 : 0)
How can I select the total weight of all rows?
With the data I have given the total weight is 2+0+1+3=6
You just need one aggregate SUM() surrounding all the conditions with no GROUP BY.
SELECT
SUM(
(CASE WHEN col1 > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN col2 > 0 THEN 1 ELSE 0 END)
+ (CASE WHEN col3 > 0 THEN 1 ELSE 0 END)
) AS total_weight
FROM your_table
http://sqlfiddle.com/#!2/b0d82/1
I am using CASE WHEN... here as it is portable across any RDBMS. Since MySQL will return a boolean 0 or 1 for the conditions though, it can be simplified in MySQL as:
SELECT
SUM(
(col1 > 0) /* returns 1 or 0 */
+ (col2 > 0)
+ (col3 > 0)
) AS total_weight
FROM your_table
http://sqlfiddle.com/#!2/b0d82/2