Mysql select unique columns from where clause - mysql

I'm trying to see if it's possible to have several unique columns in a select statement from varying where clause selections. Here is my query.
select org_id, count(org_role) as total
from organization
where org_id = 10 and org_role = 9
group by org_id;
the above works perfectly. It produces:
org_id total
10 19
Id'd like to add another column count named total2 where org_id = 10 and org_role = 7 (the count is 23). So i'd have this result:
org_id total total2
10 19 23
I'm just not sure how to edit the original above query to produce that. Any thoughts would be appreciated.

You can use conditional aggregation. For example:
select
org_id,
sum(case when org_role = 9 then 1 else 0 end) as total,
sum(case when org_role = 7 then 1 else 0 end) as total2
from organization
where org_id = 10 and org_role in (7, 9)
group by org_id;

select org_id, count(org_role) as total, count(total_2)
from organization
where org_id = 10 and org_role = 9
group by org_id;
If it does not work please send your database structure.

Related

How to Two table sum calculate

I have a two table.
I want to use the chart_num value for two tables.
Table hospital_payment_data
id chart_num treatment_fees_difference treatment_fees_check_division
1 9 200000 test
2 9 100000 test
Table advenced_payment
id chart_num advenced_amount
1 9 100000
I want result
COUNT if_treatment_fees_check_division sum_init_amount
2 200000 100000
I want treatment_fees_check_division = 'test' count
and
I want treatment_fees_check_division = 'test' condition sum treatment_fees_difference + advenced_amount
How can I achieve I want result? Would you please provide the solution?
I think you are looking for a query as below-
DEMO HERE
Note: As per your condition and data, SUM of if_treatment_fees_check_division should be 300000
SELECT A.chart_num,
COUNT(*) COUN,
SUM(CASE
WHEN treatment_fees_check_division = 'test' THEN treatment_fees_difference
ELSE 0
END) if_treatment_fees_check_division,
(
SELECT SUM(advenced_amount)
FROM advenced_payment
WHERE chart_num = A.chart_num
) sum_init_amount
FROM hospital_payment_data A
GROUP BY A.chart_num

Selecting multiple columns from two tables in which one column of a table has multiple where conditions and group them by two columns and order by one

I have two tables namely "appointment" and "skills_data".
Structure of appointment table is:
id_ap || ap_meet_date || id_skill || ap_status.
And the value of ap_status are complete, confirm, cancel and missed.
And the skills_data table contains two columns namely:
id_skill || skill
I want to get the count of total number of appointments for each of these conditions
ap_status = ('complete' and 'confirm'),
ap_status = 'cancel' and
ap_status = 'missed'
GROUP BY id_skill and year and
order by year DESC
I tried this query which only gives me count of one condition but I want to get other two based on group by and order by clauses as mentioned.
If there is no record(for example: zero appointments missed in 2018 for a skill) matching for certain conditions, then it should display the output value 0 for zero count.
Could someone please suggest me with a query whether I should implement multiple select query or CASE clause to achieve my expected results. I have lot of records in appointment table and want a efficient way to query my records. Thank you!
SELECT a.id_skill, YEAR(a.ap_meet_date) As year, s.skill,COUNT(*) as count_comp_conf
FROM appointment a,skills_data s WHERE a.id_skill=s.id_skill and a.ap_status IN ('complete', 'confirm')
GROUP BY `id_skill`, `year`
ORDER BY `YEAR` DESC
Output from my query:
id_skill | year | skill | count_comp_conf
-----------------------------------------
1 2018 A 20
2 2018 B 15
1 2019 A 10
2 2019 B 12
3 2019 C 10
My expected output should be like this:
id_skill | year | skill | count_comp_conf | count_cancel | count_missed
------------------------------------------------------------------------
1 2018 A 20 5 1
2 2018 B 15 8 0
1 2019 A 10 4 1
2 2019 B 12 0 5
3 2019 C 10 2 2
You can use conditional aggregation using case when expression
SELECT a.id_skill, YEAR(a.ap_meet_date) As year, s.skill,
COUNT(case when a.ap_status IN ('complete', 'confirm') then 1 end) as count_comp_conf,
COUNT(case when a.ap_status = 'cancel' then 1 end) as count_cancel,
COUNT(case when a.ap_status = 'missed' then 1 end) as count_missed
FROM appointment a inner join skills_data s on a.id_skill=s.id_skill
GROUP BY `id_skill`, `year`
ORDER BY `YEAR` DESC
SELECT a.id_skill,
YEAR(a.ap_meet_date) As year,
s.skill,
SUM(IF(a.ap_status IN ('complete', 'confirm'),1,0)) AS count_comp_conf,
SUM(IF(a.ap_status='cancel',1,0)) AS count_cancel,
SUM(IF(a.ap_status='missed',1,0)) AS count_missed
FROM appointment a,skills_data s WHERE a.id_skill=s.id_skill
GROUP BY `id_skill`, `year`
ORDER BY `YEAR` DESC;
Please try to use if condition along with sum.
With below query you will get output.
select id_skill ,
year ,
skill ,
count_comp_conf ,
count_cancel ,
count_missed ( select id_skill, year, skill, if ap_status ='Completed' then count_comp_conf+1, elseif ap_status ='cancelled' then count_cancel +1 else count_missed+1
from appointment a join skills_data s on (a.id_skill = s.id_skill) group by id_skill, year) group by id_skill,year
order by year desc;

Group Totals from Logs by Month

I have a log table that stores media requests by act_datetime, app_id, location_id, media_id and media_type_id. What I want is each resultset row to contain type totals for each month. For example, log records contain:
I tried using temp tables to extract records by app_id and grouping by month, but I get multiple rows for each total. I can use sub-queries, but how do I get a total row by type for each month?
Any help is greatly appreciated.
Thanks,
Brandon
EDIT
The follow code works combining shared ideas:
This query takes about 13 seconds parsing about 8.1 million rows. Is that acceptable? Lastly how do you display date as 2018-1 as one column? I'm getting errors when converting to string since the date is also used in the group and order by clauses.
I also want to try code construct sum( case when media_type_id = 1 then 1 else 0 end )... to see if get same results and speed.
Thanks for everyone's help!
Assuming this is SQL Server, and not MySQL:
SELECT DATEPART(MONTH, act_datetime) AS [Month],
COUNT(CASE WHEN app_id = 14 AND media_type_id = 1 AND location_id = 1 THEN act_datetime END) AS MP3_Messages_MO,
COUNT(CASE WHEN app_id = 14 AND media_type_id = 1 AND location_id = 2 THEN act_datetime END) AS MP3_Messages_FL,
COUNT(CASE WHEN app_id = 14 AND media_type_id = 3 AND location_id = 1 THEN act_datetime END) AS MP3_Messages_MO,
COUNT(CASE WHEN app_id = 14 AND media_type_id = 3 AND location_id = 2 THEN act_datetime END) AS MP3_Messages_FL,
COUNT(CASE WHEN app_id = 55 AND media_type_id = 1 THEN act_datetime END) AS MP3_Music,
COUNT(CASE WHEN app_id = 55 AND media_type_id = 9 THEN act_datetime END) AS ZIP_Music
FROM YourTable
GROUP BY DATEPART(MONTH, act_datetime);
Note you have included no logic for differing years, data for each Month will do a count irrespective of year.
This is also completely untested, due to lack of consumable data.

Display results in a particular format MYSQL

I have a table like
ID Name Points
1 A 10
1 A 11
1 B 11
1 B 12
1 C 12
1 C 13
2 A 8
2 A 9
2 B 9
2 B 10
2 C 10
2 C 11
I want my output to look like the following
ID Average(A) Average(B) Average(C)
1 10.5 11.5 12.5
2 8.5 9.5 10.5
The following group by query displays the output but not in above format
Select Avg(Points),ID,name from table group by Name,ID
Thanks
Wrapping your existing query in a subquery will allow you to build out a pivot table around it. The `MAX()
aggregate's purpose is only to eliminate the NULLs produced by the CASE statement, and therefore collapse multiple rows per ID down to one row per ID with a non-NULL in each column.
SELECT
ID,
MAX(CASE WHEN Name = 'A' THEN Points ELSE NULL END) AS `Average (A)`,
MAX(CASE WHEN Name = 'B' THEN Points ELSE NULL END) AS `Average (B)`,
MAX(CASE WHEN Name = 'C' THEN Points ELSE NULL END) AS `Average (C)`
FROM (
SELECT ID, AVG(Points) AS Points, Name FROM yourtable GROUP BY Name, ID
) avg_subq
GROUP BY ID
Here is a live demonstration on SQLFiddle

Query with multiple subqueries required in Mysql

I am looking for some query help
here is the following table data
Name Runs Status
Ram 50 out
Ram 103 not out
Krish 51 out
Sam 15 out
Ram 15 out
Krish 78 not out
I am expecting a single query to give the folllowing results
Name Total >100 >50&<100 TotalTimes Notout
Ram 168 1 1 3 1
Sam 15 0 0 1 0
Krish 129 0 2 2 1
I am able to write the query to get the total, Totaltimes with the help of Group By functionalities, I am stuck with the rest
Here is the query I have come up
select Name, sum(Runs) as total, count(*) as totalTimes
from tempTable
where classID IN (Select classID from upcoming_Clases where classes_id=175)
group by Name order by total desc
I am using the Mysql Database
You can do this using case:
select Name,
sum(Runs) as total,
count(case when Runs>100 then 1 end) `>100`,
count(case when Runs>50 and Runs<100 then 1 end) `>50&<100`,
count(*) as totalTimes,
count(case when Status='not out' then 1 end) `Not Out`
from tempTable
where classID IN (Select classID from upcoming_Clases where classes_id=175)
group by Name order by total desc
You can use SUM() together with IF() to test your criteria:
SELECT
Name,
SUM(Runs) AS Total,
SUM(IF(Runs>100, 1, 0)) AS `>100`,
SUM(IF(Runs>50 AND Runs<100), 1, 0) AS `>50&<100`,
COUNT(*) AS TotalTimes,
SUM(IF(Status='not out', 1, 0)) AS Notout
FROM tempTable
WHERE classID IN (SELECT classID FROM upcoming_Clases WHERE classes_id = 175)
GROUP BY Name
ORDER BY Total DESC