how create a ' one to many ' sql query statement - mysql

i have a table called(center_info) which which has a student's information and their total bills paid and total balance remained. and another table called (center_payments) which has records of each single date of bill paid by a student.
I want to join records of a student in table 1(center_info), to every date he paid a bill in table 2(center_payments)
below are the records in center_info:
id | student | term | bill | total_paid | total_balance | last_date_of_pymt |
---+---------+------+------+------------+---------------+-------------------+
5 mary 1 400 200 -200 6 / june / 2019
6 john 1 500 300 -200 2 / june / 2019
7 grace 2 450 400 -50 17 / august / 2019
8 mike 2 450 100 -350 15 / august / 2019
and the below are the different dates of payments in center_payments:
id | student | paid | balance | date | term |
---+---------+------+---------+--------------+------+
5 mary 100 -300 3 / june /2019 1
5 mary 100 -200 6 / june /2019 1
6 john 150 -350 1 / june /2019 1
6 john 150 -200 2 / june /2019 1
7 grace 400 -50 17 / aug /2019 2
8 mike 50 -400 5 / aug /2019 2
8 mike 50 -350 5 / aug /2019 2
I want to join records of students in table 1 and all their individual payments in table 2 where term(column)=1
currently am only able to print out a selected student and view all his records from the two tables with this code :
int row = c_FirstTerm.getSelectedRow();
try{
String table_click=(c_FirstTerm.getModel().getValueAt(row,0).toString());
String sgl="select center_info.id,center_info.student,center_info.bill,center_info.Term,center_info.total_paid,center_info.total_balance,center_info.last_date_of_pymt,center_payments.paid,center_payments.balance,center_payments.date from center_info INNER JOIN center_payments on center_info.term=center_payments.term and center_info.id=center_payments.id and center_info.Student='"+table_click+"'";
}catch(Exception e){
JOptionPane.showMessageDialog(null,e);
}
but assuming I don't select a particular student, how do I create a one-to-many relationship for students and their individual payments from both tables where term=1. eg like this:
//first group
id | student | paid | balance | date | term |
---+---------+------+---------+--------------+------+
5 mary 100 -300 3 / june /2019 1
5 mary 100 -200 6 / june /2019 1
id | student | term | bill | total_paid | total_balance | last_date_of_pymt |
---+---------+------+------+------------+---------------+-------------------+
5 mary 1 400 200 -200 6 / june / 2019
_____________________________________________________________________________
//next group
id | student | paid | balance | date | term |
---+---------+------+---------+--------------+------+
6 john 150 -350 1 / june /2019 1
6 john 150 -200 2 / june /2019 1
id | student | term | bill | total_paid | total_balance | last_date_of_pymt |
---+---------+------+------+------------+---------------+-------------------+
6 john 1 500 300 -200 2 / june / 2019

Related

MySQL query SELECT multiple date brackets from table

Consider the following 2 MySQL tables:
Table - Commission
id
employee_id
from_date
to_date
orders_from
orders_to
commission
1
1
2021-05-01
2021-05-05
1
10
1
2
1
2021-05-06
2021-05-10
1
10
1
3
1
2021-05-11
2021-05-15
1
10
1
4
1
2021-05-01
2021-05-05
11
20
2
5
1
2021-05-06
2021-05-10
11
20
2
6
1
2021-05-11
2021-05-15
11
20
2
7
1
2021-05-01
2021-05-05
21
30
3
8
1
2021-05-06
2021-05-10
21
30
3
9
1
2021-05-11
2021-05-15
21
30
3
Table - Orders
id
employee_id
order_date
price
An employee will get a commission based on the number of his orders during each date bracket in the "commission" table.
So for example for the first 10(1-10) orders from May 1st till May 5th he'll get 1% for each order and then for the next 10(11-20) he'll get 2% for each of those and so on.
I'm going to have a form where the manager will be able to select 2 dates from a calendar in order to see what the employee should be paid.
I want to create a MySQL query that will give me all the date brackets from the table "commission" that include the 2 dates the manager has selected?
So lets say that we select the following period:
from 2021-05-03 to 2021-05-09
How will I get all just the rows for those dates? Which in this case would be ids:1,2,4,5,7,8.
P.S. Data and use case presented here are simplified for better readability/understanding
EDIT
After Thomas G's comment
Lets say that employee with id 1 has the following orders
| id | employee_id | order_date | price |
| :--- | :---------- | :--------- | :---- |
| 1 | 1 | 2021-05-03 | 100 |
| 2 | 1 | 2021-05-07 | 100 |
| 3 | 1 | 2021-05-13 | 100 |
Now I want to check what to pay that employee for the period 2021-05-03 - 2021-05-09.
In that period only the orders 1 and 2 are applicable to be paid.
If we check the commission table we can see that for this period we need records 1 and 2.
How can get rows 1 and 2 from the commission table, using the 2 dates provided, 2021-05-03 and 2021-05-09?

How to write an SQL query to calculate the average for three consecutive values?

I have a table like this
userID time NoOfVisits
1 2014 50
2 2015 60
3 2016 70
4 2017 80
5 2018 90
6 2019 100
I need to write a sql query which will print time and average of past 3 years NoOfVisits for a particular site.
output should be as
userID time NoOfVisits
1 2014 50.0000
2 2015 55.0000
3 2016 60.0000
4 2017 70.0000
5 2018 80.0000
6 2019 90.0000
Explanation :
For user Id 6 (80+90+100)/3=90.0000
Please help me to solve this problem.
You can use a cumulative average, available in MySQL 8+:
select t.*,
avg(visits) over (order by time rows between 2 preceding and current row) as avg_visits_3
from t;
Assuming there are no gaps between the years (like your sample data), you can self join the table and group by userid, time to get the average:
select
t.userid, t.time, avg(tt.noofvisits) NoOfVisits
from tablename t inner join tablename tt
on tt.time between t.time - 2 and t.time
group by t.userid, t.time
See the demo.
Results:
| userid | time | NoOfVisits |
| ------ | ---- | ---------- |
| 1 | 2014 | 50 |
| 2 | 2015 | 55 |
| 3 | 2016 | 60 |
| 4 | 2017 | 70 |
| 5 | 2018 | 80 |
| 6 | 2019 | 90 |

mysql getting average of client per day in a month

SELECT COUNT(client_ID) / DAY(LAST_DAY(dateRequested))
FROM `tbl_client`
WHERE dateRequested BETWEEN DATE_FORMAT(dateRequested,'%Y-%m-01') AND LAST_DAY(dateRequested)
I want to show the average of client per day in the month
client_ID | dateRequested
1 | 2018-07-04
2 | 2018-07-05
3 | 2018-07-06
4 | 2018-07-07
5 | 2018-08-04
6 | 2018-08-06
7 | 2018-08-09
i want to show
Average | Month
4 | July 2018
3 | August 2018
Try below query:
SELECT COUNT(client_ID),concat(month(dateRequested),year(dateRequested))
FROM `tbl_client`
WHERE dateRequested BETWEEN DATE_FORMAT(dateRequested,'%Y-%m-01') AND LAST_DAY(dateRequested)
group by concat(month(dateRequested),year(dateRequested))

Building SQL query between two number set

Hi i have a table regd like this
name | year | month
james| 2017 | 2
stacy| 2017 | 4
josh | 2017 | 8
june | 2017 | 9
mary | 2018 | 1
hawk | 2018 | 2
sim | 2018 | 3
How can I select all the people between month 8 of year 2017 to month 3 of year 2018.
Thank you for your help and suggestions.
You can write condition like below
year * 100 + month between 201708 and 201803
where 201708 = 2017 * 100 + 8
and 201803 = 2018 * 100 + 3

mysql complex query for monthly report

employee makes entry in the following table when starting new task
from home or office
[tablename=CHECK]
c_id c_sdate c_emp c_task
-------------------------------------------------
1 2013-05-01 01:01:00 1 26 //date 01 from home-----
2 2013-05-01 08:11:00 1 27 //date 01 from office--- Present
3 2013-05-02 03:41:00 1 28 //date 02 from home---
4 2013-05-02 09:12:00 1 29 //date 02 from office-
5 2013-05-02 22:32:00 1 30 //date 02 from home---Present
6 2013-05-03 01:43:00 1 31 //date 03 from home
7 2013-06-03 23:25:00 1 32 //date 03 from home----------Homework
8 2013-06-03 02:15:00 2 33 //other employee
an employe will be considered as present if there 1 or many records where time between 8am and 8pm
an employe will be considered as workedFromHome if there 1 or many records where time NOT between 8am and 8pm, and not present on that day
note: do not count a day as workedFromHome if there is any record time between 8am and 8pm (means workedFromHome is only counted if he is not resent on that day)
I want to display monthly report of a employee eg. c_emp=1 for month eg. 5
like this in 1 query
c_emp presentCount HW_Count
1 3 1
or separatly query 1
c_emp presentCount
1 3
and query 2
c_emp HW_Count
1 1
I have tried for counting present working fine
select count(distinct(date_format(c_sdate,'%e'))) as count
from ita_check
where date_format(c_sdate,'%m')=5
and c_emp=1
and date_format(c_sdate,'%H%i')>=800
and date_format(c_sdate,'%H%i')<=2000
and for counting fromHome giving wrong count
select count(distinct(date_format(c_sdate,'%e'))) as count
from ita_check
where date_format(c_sdate,'%m')=5
and c_eid=1
and c_id not in (
select c_id
from ita_check
where date_format(c_sdate,'%m')=5
and c_eid=1
and (date_format(c_sdate,'%H%i')<=800 or date_format(c_sdate,'%H%i')>=2000)
)
and date_format(c_sdate,'%H%i')<800
or date_format(c_sdate,'%H%i')>2000
in above query for counting Working
the sub query returns 1 and 2
while the outer eliminate c_id=2 but not c_id=1
Try this query
SELECT c_emp,
sum(if(cnt>=1,1,0)) as Office,
count(*)-sum(if(cnt>=1,1,0)) as WFH from (
select c_emp, Date(c_sdate),
sum(if(c_sdate BETWEEN Date(c_sdate) + interval 8 hour
AND Date(c_sdate) + interval 20 hour, 1, 0)) as cnt
from table1
group by c_emp, Date(c_sdate)) tmp
group by c_emp
SQL FIDDLE:
| C_EMP | OFFICE | WFH |
------------------------
| 1 | 2 | 2 |
| 2 | 0 | 1 |
For monthly report
SELECT c_emp, date_format(c_date, '%c %Y') as Mnth,
sum(if(cnt>=1,1,0)) as Office,
count(*)-sum(if(cnt>=1,1,0)) as WFH from (
select c_emp, Date(c_sdate) as c_date,
sum(if(c_sdate BETWEEN Date(c_sdate) + interval 8 hour
AND Date(c_sdate) + interval 20 hour, 1, 0)) as cnt
from table1
group by c_emp, Date(c_sdate)) tmp
group by c_emp,Mnth
SQL FIDDLE:
| C_EMP | MNTH | OFFICE | WFH |
---------------------------------
| 1 | 5 2013 | 2 | 1 |
| 1 | 6 2013 | 0 | 1 |
| 2 | 6 2013 | 0 | 1 |