I have the following query:
SELECT folders.name folder, s.name `schedule`, ms.month as 'month', concat(s.start, " - ", s.end) `time`,
p.name 'profession', (select count(*) from employees where profession_id = p.id) as "count_employees"
FROM schedules s
JOIN folders ON folders.id = s.folder_id
JOIN month_schedules ms ON ms.schedule_id = s.id
LEFT JOIN schedule_professions sp ON sp.schedule_id = s.id
JOIN professions p ON p.id = sp.profession_id
WHERE s.company_id = 82 AND ms.year = 2021 AND ms.month = 2
This query returns the following table
folder
schedule
month
time
profession
count_employees
folder_a
schedule_a
2
0
profession_a
3
folder_a
schedule_a
2
0
profession_b
5
folder_a
schedule_a
2
0
profession_c
1
folder_a
schedule_b
2
0
profession_a
1
folder_a
schedule_b
2
0
profession_b
0
folder_a
schedule_b
2
0
profession_c
0
but what I want is this:
folder
schedule
month
time
profession_a
profession_b
profession_c
folder_a
schedule_a
2
0
3
5
1
folder_a
schedule_b
2
0
1
0
0
The number of professions is unknown, so has to be dynamically calculated.
I tried using GROUP_CONCAT and CONCAT, but I'm a newbie with SQL, so I didn't have any success.
SELECT
folders.name folder,
s.name `schedule`,
ms.month as 'month',
concat(s.start, " - ", s.end) `time`,
count(CASE WHEN p.name="profession_a" THEN 1 ELSE 0 END) 'profession_a',
count(CASE WHEN p.name="profession_b" THEN 1 ELSE 0 END) 'profession_b',
count(CASE WHEN p.name="profession_c" THEN 1 ELSE 0 END) 'profession_c',
(select count(*) from employees where profession_id = p.id) as "count_employees"
FROM schedules s
JOIN folders ON folders.id = s.folder_id
JOIN month_schedules ms ON ms.schedule_id = s.id
LEFT JOIN schedule_professions sp ON sp.schedule_id = s.id
JOIN professions p ON p.id = sp.profession_id
WHERE s.company_id = 82 AND ms.year = 2021 AND ms.month = 2
You only need to check if the GROUP BY is correct, i did not do that check.... 😉
Related
im trying to sum and show all registries in mysql.
i have this query:
select `deliverables`.*,
`users`.`first_name`,
`users`.`last_name`
from `deliverables`
inner join `users` on `users`.`id` = `deliverables`.`user_id`
where `deliverables`.`specialty_id` = '11' and
`deliverables`.`role_id` <> '1'
and the output is:
file_code file_name dedicated_hours
0001asder test-file.docx 4
0001as234w asdf.doc 2
jgfjh2546 test.docx 4
0001asder test-file.docx 1
0001asder test-file.docx 0
0001asder test-file.docx 0
i need sum the dedicated_hours where file_code is equal so it should looks like this:
file_code file_name dedicated_hours sum
0001asder test-file.docx 4 5
0001as234w asdf.doc 2 2
jgfjh2546 test.docx 4 4
0001asder test-file.docx 1 5
0001asder test-file.docx 0 5
0001asder test-file.docx 0 5
im using sum(dedicated_hours) and group by file_code but it only show:
file_code file_name dedicated_hours sum
0001asder test-file.docx 4 5
0001as234w asdf.doc 2 2
jgfjh2546 test.docx 4 4
How can i sum and show all registries at the same time?
Your MySQL version (5.0.12) does not support Window Functions (it should be a decent incentive enough to upgrade to get the latest goodies :)
Nevertheless, we can use a Derived Table to determine the aggregated SUM() for a file_code separately. Then, we can simply Join back to the main tables, to show the sum column.
SELECT
d.file_code,
d.file_name,
d.dedicated_hours,
dt.sum,
u.first_name,
u.last_name
FROM deliverables AS d
JOIN users AS u
ON u.id = d.user_id
JOIN
(
SELECT file_code,
SUM(dedicated_hours) AS sum
WHERE speciality_id = '11' AND
role_id <> '1'
GROUP BY file_code
) AS dt
ON dt.file_code = d.file_code
WHERE d.speciality_id = '11' AND
d.role_id <> '1'
MySQL 8.0.2 and above solution would be simply using SUM(..) OVER (..)
SELECT
d.file_code,
d.file_name,
d.dedicated_hours,
SUM(d.dedicated_hours) OVER (PARTITION BY d.file_code) AS sum,
u.first_name,
u.last_name
FROM deliverables AS d
JOIN users AS u
ON u.id = d.user_id
WHERE d.speciality_id = '11' AND
d.role_id <> '1'
I've two tables as below:
1. tbl_student:
id name
1 raj
2 raja
3 raju
4 rajan
tbl_attendance
id student_id month attended_days
1 1 1 6
2 1 2 16
3 8 1 8
4 7 2 14
5 8 2 13
6 7 1 11
I need to join these two tables combining multiple rows for each month for each student from tbl_attendance into a single row to obtain a result like this:
id name month attended_days month attended_days
1 raj 1 6 2 16
7 raja 1 11 2 14
8 rajan 1 8 2 13
Thanks in advance for any help.
Instead of displaying month value in each of the records,
you can use them as column headers and attendance as their value.
Use pivot type solution to achieve required solution.
Example:
select s.id as student_id
, s.name as student_name
, max( case when a.month = 1 then a.attended_days else null end ) as month_1
, max( case when a.month = 2 then a.attended_days else null end ) as month_2
, max( case when a.month = 3 then a.attended_days else null end ) as month_3
-- ...
, max( case when a.month = 12 then a.attended_days else null end ) as month_12
from table_student s
left join table_attendance a on s.id = a.student_id
group by s.id, s.name
Your question is not very complete, but i think you want something like this:
select s.*,
coalesce(a1.month, a2.month, a3.month) as month,
coalesce(a1.attended_days , a2.attended_days , a3.attended_days ) as attended_days
from table_student s
left join table_attendance a1 on s.id = a1.student_id and a1.month = 1
left join table_attendance a2 on s.id = a2.student_id and a2.month = 2
left join table_attendance a3 on s.id = a3.student_id and a3.month = 3
The previous code is used if you want to show all months in one column. For multiple columns, you can use this example:
select s.*,
a1.month as month_1,
a2.month as month_2,
a3.month as month_3,
a1.attended_days as attended_days_1,
a2.attended_days as attended_days_2,
a3.attended_days as attended_days_3
from table_student s
left join table_attendance a1 on s.id = a1.student_id and a1.month = 1
left join table_attendance a2 on s.id = a2.student_id and a2.month = 2
left join table_attendance a3 on s.id = a3.student_id and a3.month = 3
Do this for all the 12 months. I used 3 as example.
I was trying to get count of three columns by using SUM(), when I execute the query, it says '#1111 - Invalid use of group function'. I tried correcting the group functions, even though it shows the error.
I need the perfect count of columns 2,3,4
SELECT c.name,
SUM(CASE WHEN COUNT(distinct cmc.id) = COUNT(distinct ccc.id) THEN 1 ELSE 0 END) AS "COND1",
SUM(CASE WHEN COUNT(distinct cmc.id) > 0 AND COUNT(distinct cmc.id) != COUNT(distinct ccc.id) THEN 2 ELSE 0 END) AS "COND2",
SUM(CASE WHEN COUNT(distinct cmc.id) = 0 THEN 3 ELSE 0 END) AS "COND3"
FROM
lesson_modules_completion cmc
INNER JOIN lesson_modules cm ON cmc.lessonmoduleid = cm.id
INNER JOIN lesson_completion_settings ccc ON cm.lesson = ccc.lesson
INNER JOIN lesson c ON cm.lesson = c.id
INNER JOIN user u ON u.id = cmc.userid
WHERE ccc.criteriatype=4
GROUP BY c.name
I need the count of each user has Completed modules, Inprocess modules and Notstarted modules for each course, where getting the count of userids from table CC by taking courseia from table CM, get number of modules that an user has completed from each course.
(A course can have morethan one module and a course can have number of users attempted all modules, few modules or not attempted at all).
So, I need number of users - has done number of modules - in a course. (3 logics)
(COND1 i.e.,Completed.Users ) : If number of modules attempted is equal to number of modinstance from table CMS (ex: no. of modules attempted by a user per course= 9, no.modinstance = 9. Because 7 is not equal to 9, They are completed.)
(COND2 i.e.,Inprocess.Users ) : Number of modules attempted should be >0, but not equal to [count(modinstance) per course] (ex: no. of modules attempted by a user per course= 7 , no.modinstance = 9. Because 7 is not equal to 9, They are Inprocess.)
(COND2 i.e.,Nostart.Users ) : Number of modules attempted should be equal to 0, (ex: no. of modules attempted by a user per course= 0. They are Notstarted).
You can refer my query, It was all doing good, but I need the count of COND1, COND2, COND3
I need the OUTPUT :
lesson COND1 COND2 COND3
5 65 32 6
6 40 12 15
8 43 56 0
9 0 7 9
select lesson,sum(COND1) as COND1, sum(COND2) as COND2,sum(COND3) as COND3
from
(
SELECT c.name,
ccc.lesson,
CASE WHEN COUNT(distinct cmc.id) = COUNT(distinct ccc.id) THEN 1 ELSE 0 END AS "COND1",
CASE WHEN COUNT(distinct cmc.id) > 0 AND COUNT(distinct cmc.id) != COUNT(distinct ccc.id) THEN 2 ELSE 0 END AS "COND2",
CASE WHEN COUNT(distinct cmc.id) = 0 THEN 3 ELSE 0 END AS "COND3"
FROM
lesson_modules_completion cmc
INNER JOIN lesson_modules cm ON cmc.lessonmoduleid = cm.id
INNER JOIN lesson_completion_settings ccc ON cm.lesson = ccc.lesson
INNER JOIN lesson c ON cm.lesson = c.id
INNER JOIN user u ON u.id = cmc.userid
WHERE ccc.criteriatype=4
GROUP BY c.name,ccc.lesson
) t
group by lesson
In the below query I'm getting some odd results -- specifically, I'm getting the same counts for both categories (current year and all time) and I can't figure out why that would be. Here's my query:
SELECT eventlist.isid, eventlist.name, COUNT(currentyearcount.arid) AS currentyearcount, COUNT(allreports.arid) AS allreports
FROM eventlist
LEFT JOIN artist_reports currentyearcount ON eventlist.isid = currentyearcount.CompanyID AND currentyearcount.event_year = 2015
JOIN artist_reports allreports ON eventlist.isid = allreports.CompanyID
GROUP BY eventlist.isid
I'm getting results like this:
isid name currentyearcount allreports
1234 Name1 33 33
5678 Name2 105 105
9012 Name3 0 63
I'm not sure why Name3 would show 0 for currentyearcount when really they should all be showing 0 as there aren't any reports for the current year yet.
UPDATE: Here's the correct query thanks to Aleksandar's comments:
SELECT eventlist.isid, eventlist.name, SUM(CASE WHEN artist_reports.arid IS NOT NULL AND artist_reports.event_year = 2015 THEN 1 ELSE 0 END) AS currentyearcount, SUM(CASE WHEN artist_reports.arid IS NOT NULL THEN 1 ELSE 0 END) AS totalcount
FROM eventlist
LEFT JOIN artist_reports ON eventlist.isid = artist_reports.CompanyID
GROUP BY eventlist.isid
I have 2 tables, orders and order_lineitems.
orders contains the order status info (sold date, invoice no, type of sale, etc)
order_lineitems contains the item(s) for each order in a one to many relationship.
Since we provide shipping info by line item, ship_date is in the order_lineitems table, null if not shipped, a date if it is shipped.
I am trying to pull the orders where all items have shipped by comparing the number of line item rows against the line item rows that have a ship date. While I have successfully pulled all that info, I am unable to make the last step, limiting the result set to include only the completely shipped orders (number of rows = number of rows where ship_date is not null).
I know I am missing something simple, but just don't see it..
select sum(custom.lineitems) as totalitems, sum(custom.shipped) as totalshipped,
custom.invoice, z.shipregion
from (
select a.invoice, count(a.invoice) as lineitems, 0 as shipped
from order_lineitem a
group by a.invoice
UNION ALL
select b.invoice, 0 as notshipped, count(b.ship_date) as shipped
from order_lineitem b
where b.ship_date is not null
group by b.invoice
) as custom
left join orders z on custom.invoice = z.invoice
where z.result = 0
and z.respmsg like 'Approved%'
and z.shipregion <> 'PENDING'
and z.cancelorder = 0
group by custom.invoice;
This returns a result set like so (one row for each invoice in the DB)
totalitems totalshipped invoice shipregion
4 2 1000 REGION08
1 1 10001 REGION07
1 1 10004 REGION05
3 1 10006 REGION05
2 2 10007 REGION04
1 1 10008 REGION08
7 7 10009 REGION01
1 1 1001 REGION08
What I am looking for is a result set like this - only where totalitems = totalshipped
totalitems totalshipped invoice shipregion
1 1 10001 REGION07
1 1 10004 REGION05
2 2 10007 REGION04
1 1 10008 REGION08
7 7 10009 REGION01
1 1 1001 REGION08
Use HAVING clause
SELECT a.invoice, z.shipregion, COUNT(a.invoice) AS lineitems,
SUM(CASE WHEN a.ship_date IS NOT NULL THEN 1 ELSE 0 END) AS shipped
FROM order_lineitem a
LEFT JOIN orders z ON a.invoice = z.invoice AND z.result = 0 AND z.cancelorder = 0 AND
z.respmsg LIKE 'Approved%' AND z.shipregion <> 'PENDING'
GROUP BY a.invoice HAVING lineitems = shipped
OR
SELECT a.invoice, a.shipregion, a.lineitems, a.shipped
FROM (SELECT a.invoice, z.shipregion, COUNT(a.invoice) AS lineitems,
SUM(CASE WHEN a.ship_date IS NOT NULL THEN 1 ELSE 0 END) AS shipped
FROM order_lineitem a
LEFT JOIN orders z ON a.invoice = z.invoice AND z.result = 0 AND z.cancelorder = 0 AND
z.respmsg LIKE 'Approved%' AND z.shipregion <> 'PENDING'
GROUP BY a.invoice
) AS a WHERE a.lineitems = a.shipped
One more outer query needed.
select * from
(
\\Your whole query here
) as Result
where Result.totalitems = Result.totalshipped