How resolve null value when create view - mysql

I need to create a view like this:
STUDENT JANUARY FEBRUARY MARCH ........ DECEMBER
miki 10.23 23.23 0 0
Goku 10 0 0 0
Luffy 0 0 0 0
I have a table studentMovement(id_studentmovement,id_student,month,year,cost,date,id_university,university_name)
that represents every sigle cost for the student in this month and year. it contains the real cost that some students had done in a certain course in a certain university.
Table Students(id_student,name)
Table University(id_university,university name);
I want to get for all university, all student and for single student the cost for every months ( also if the student doesn't spent anything in a certain university:
This sql query is this:
select year(sm.date) as year, s.id_student, s.name,
sum(amount) as year_amount,
sum(case when month(sm.date) = 1 then amount else 0 end) as january,
sum(case when month(sm.date) = 2 then amount else 0 end) as february,
. . .
sum(case when month(sm.date) = 12 then amount else 0 end) as december,
u.id_university as id_university,
u.university_name as university_name
from ((schema.students s left join
schema.studentMovement sm
on s.d_student = sm.id_student ) inner join schema.university u on u.id_university=sm.id_university)
group by year(sm.date) as year, s.id_student, s.name, u.id_university,
u.university_name
THe query put wrong value and some value are null.Anyone can help me?

Null values appear from your do Left Join Statement. Because it returns all records from the left table, and the matched records from the right table. The result is NULL from the right side, if there is no match.
select
year(sm.date) as year,
s.id_student,
s.name,
sum(amount) as year_amount,
sum(case when month(sm.date) = 1 then amount else 0 end) as january,
sum(case when month(sm.date) = 2 then amount else 0 end) as february,
. . .
sum(case when month(sm.date) = 12 then amount else 0 end) as december,
u.id_university as id_university,
u.university_name as university_name
from
((schema.students s
inner join schema.studentMovement sm on s.d_student = sm.id_student )
inner join schema.university u on u.id_university=sm.id_university)
group by
year(sm.date),
s.id_student,
s.name,
u.id_university,
u.university_name
If you want to not see Null change your Left Join to Inner Join instead because Inner Join selects records that have matching values in both tables.

Try just using inner joins in the from clause:
FROM schema.students s JOIN
schema.studentMovement sm
ON s.d_student = sm.id_student JOIN
schema.university u
ON u.id_university = sm.id_university

Maybe you noticed some wrong values in the amount field: try to delete the double quotes
COALESCE(SUM(sm.amount), 0) AS amount,

Related

how to get two table joined data exclude some conditional data of one table in mysql?

I have two tables: Student and fee
student
sid
name
roll_no
1
John
22
2
Karina
32
3
Navin
42
fee
fid
s_id
month
fee
1
2
January
1000
2
3
January
1200
3
2
Fabruary
1000
I want to get students (who not paid fee) for Fabruary : like this...
Student id
Name
Roll No
January
February
1
John
22
0
0
3
Navin
42
1200
0
My code is :
SELECT s.sid,s.name,s.roll_no,f.fee
from student s
left join
fee f
ON f.fid = s.sid
AND f.month = 'January'
where s.sid NOT IN (SELECT s_id from fee
where month = 'February')
order by c.id;
I got zero value in both months for all students
------Thanks in advance-------
After correction this code works in mysql workbench but not in java application.
SELECT
s.sid,s.name,s.roll_no, ifnull(f.fee,0) as pre_month,0 as current_month
from student s
left join
fee f
ON f.s_id = s.sid
AND f.month = 'January'
where s.sid NOT IN
(SELECT s_id from fee
where month = 'February')
order by s.sid;
For the results you want, I would suggest conditional aggregation and a having clause:
SELECT s.sid, s.name, s.roll_no,
SUM(CASE WHEN f.month = 'January' THEN f.fee ELSE 0 END) as january,
SUM(CASE WHEN f.month = 'February' THEN f.fee ELSE 0 END) as february
FROM student s LEFT JOIN
fee f
ON f.fid = s.sid AND f.month = 'January'
GROUP BY s.sid, s.name, s.roll_no
HAVING SUM(CASE WHEN f.month = 'February' THEN f.fee ELSE 0 END) = 0 AND
SUM(CASE WHEN f.month = 'January' THEN f.fee ELSE 0 END) > 0;
Here is a db<>fiddle.
Note that storing month names in a column is usually a really bad idea. It does not distinguish between the years, for instance. It is much better to use a date.
You can use a left join to join the students with their fees, and then a having clause to filter the list down to those who don't have one for February. The below query should get you a list of all students who did not pay a fee for February.
It also looked like you might be using the wrong column on the fee table for the join. It looked like you might want s_id instead of fid.
select s.*
from students s
left join fee f on f.s_id=s.sid and f.month='February'
having f.fid is null;

Create view that shows how much a student a spent

I need to create a view like this:
STUDENT JANUARY FEBRUARY MARCH ........ DECEMBER
miki 10.23 23.23 0 0
Goku 10 0 0 0
I have a table studentMovement(id_studentmovement,id_student,month,year,cost,date) that represents every sigle cost for the student in this month and year. it contains the real cost that some students had done.
Another table is Month(id_month), that has all month id (January==1 February==2 etc).
Table Students(id_student,name)
Another view is Years(id_year), it contains some year.
I want to get for a year, for all students in the table student(also the student that don't have outputs) and for all month(if there is an output in this month the value is 0) , I want get the sum all cost. SO my view is this
CREATE
ALGORITHM = UNDEFINED DEFINER = "***" #"%" SQL SECURITY DEFINER VIEW "schema"."v_student_table" AS select
"s"."id_student" AS "id_student",
"s"."name" AS "name",
"m"."id_month" AS "id_month",
coalesce(sum("sm"."amount"),0) AS "amount",
coalesce(month("sm"."date"),"month"."id_month") AS "month",
coalesce(year("sm"."date"),"year"."id_year") AS "anno"
from
((("schema"."studentMovement" "sm"
left join "schema"."students" "s" on "s"."id_student"="sm"."id_student")
left join "schema"."month" "m" on "m"."id_month"="sm".id_month")
inner join "schema"."years" "y" on "y"."id_year"="sm".id_year")
group by
coalesce(year("sm"."date"),"year"."id_year"),
coalesce(month("sm"."date"),"month"."id_month"),
"s"."id_student",
"s"."name",
"m"."id_month"
The problem is if there isn't a cost for a month in a year, I need to put 0 like value but with this query it doesn't do this.
the problem is the studentMovement has the real outputs. in the example above Goku has only one cost that is in jenuary but the student goku is not present for FEBRUARY etc, Anyone can help me?
You seem to want something like this:
select year(sm.date) as year, s.id_student, s.name,
sum(amount) as year_amount,
sum(case when month(sm.date) = 1 then amount else 0 end) as january,
sum(case when month(sm.date) = 2 then amount else 0 end) as february,
. . .
sum(case when month(sm.date) = 12 then amount else 0 end) as december,
"m"."id_month" AS "id_month",
coalesce(sum("sm"."amount"),0) AS "amount",
from schema.students s join
schema.studentMovement sm
on s.d_student = sm.id_student
group by year(sm.date) as year, s.id_student, s.name;
The . . . is the logic for the remaining months.

SQL Group Function

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

SQL Select to spread row data to columns

I have this select
SELECT
products.prod_name, SUM(beg_inv - end_inv) AS inv,
MONTH(task_date) MONTH
FROM performances
INNER JOIN tasks
ON performances.task_id = tasks.task_id
INNER JOIN people
ON people.person_id = tasks.emp_id
INNER JOIN products
ON performances.prod_id = products.prod_id
WHERE YEAR(task_date) = '2013'
GROUP BY performances.prod_id, MONTH(task_date)
ORDER BY MONTH(task_date), prod_name
and its out put is:
Prod name inv month
Product 1 5 3
Product 1 10 5
I would want to spread it like this:
Product Name January February March April May June July August September October November December
Product 1 5 10
Is it possible without having to do a Pivot and just in select?
Just do the pivot in SQL like this:
SELECT products.prod_name,
SUM(case when MONTH(task_date) = 1 then beg_inv - end_inv end) AS January,
SUM(case when MONTH(task_date) = 2 then beg_inv - end_inv end) AS February,
SUM(case when MONTH(task_date) = 3 then beg_inv - end_inv end) AS March,
. . .
FROM performances
INNER JOIN tasks
ON performances.task_id = tasks.task_id
INNER JOIN people
ON people.person_id = tasks.emp_id
INNER JOIN products
ON performances.prod_id = products.prod_id
WHERE YEAR(task_date) = 2013
GROUP BY products.prod_name,
ORDER BY products.prod_name,;
Note that this also requires small changes to the GROUP BY and ORDER BY clauses.

how to write query to get the data based on month?

My Database table is::
attendence date admission number attendence
2013-10-2 LSTM-0008/2013-2014 present
2013-10-19 LSTM-0008/2013-2014 absent
2013-9-20 LSTM-0008/2013-2014 present
above one is my database table.
i want to display table like this based on database table:
MonthName totalWorkingDays Present absent
october 26 1 1
november 26 1 0
i wrote mysql query like this:
SELECT DISTINCT monthname(attendencedate)as monthname , COUNT (*) as totalworking days,
(SELECT COUNT(*) FROM lstms_attendence WHERE attendence='present' AND addmissionno='LSTM-0008/2013-2014') as present,
(SELECT COUNT(*) FROM lstms_attendence WHERE attendence='absent' AND addmissionno='LSTM-0008/2013-2014') as absent
FROM lstms_attendence
WHERE addmissionno='LSTM-0008/2013-2014'
GROUP BY attendencedate;
its not working for me any one give me suggestions.
Try this:
SELECT monthname(attendencedate) AS monthname,
COUNT(*) AS totalworking_days,
SUM(CASE WHEN attendence = 'present' THEN 1 ELSE 0 END) AS present,
SUM(CASE WHEN attendence = 'absent' THEN 1 ELSE 0 END AS absent
FROM lstms_attendence
WHERE addmissionno = 'LSTM-0008/2013-2014'
GROUP BY monthname(attendencedate);
It will SUM 1 for every row that has attendence = 'present' in the present column and 0 otherwise. The same for attendence = 'absent'