With these tables:
workshops
WorkshopID | WorkshopName | WorkshopLimit
1 Workshop A 10
2 Workshop B 20
3 Workshop C 30
4 Workshop D 40
5 Workshop E 50
workshop_participants
ParticipantID | RegistrantID | WorkshopID
1 1 1
2 1 2
3 2 3
4 3 2
5 3 5
6 4 1
7 4 4
8 5 4
Is it faster to just subtract and update the number of WorkshopLimit for each registration, or count the total number of participants of a certain workshop then subtract it to the WorkshopLimit (without updating WorkshopLimit) ?
An example of usage for this is when I will check the remaining slot of a certain workshop.
It is faster to run a simple select statement like SELECT WorkshopLimit FROM workshops WHERE id = 42 to read a simple value from a datarow to check the remaining open seats in a workshop than to use a more complex query involving an aggregate function like COUNT(...) to calculate the remaining open seats on demand all the time.
However, it is most likely not speed-wise relevant at all if you update the remaining open seats value in the workshops table at each registration OR if you calculate the remaining seats on the fly when needed. They are both too fast to be relevant for your decision to use one approach or the other.
TL;DR = It doesn't matter.
It depends on how strict of your WorkshopLimit. If over-registration is prohibited, updating WorkshopLimit is an easy way to guard the rule. Make registration and updating WorkshopLimit in a transaction, if WorkshopLimit is less than 0, rollback the transaction and cancel the registration.
If over-registration is allowed, both solution is acceptable. As if you don't have huge data volume, performance difference should be minor.
Related
I'm coding an online timetable website which holds all your current subjects you are attending at school and contains slots to write work and it's due date. Mainly for my own personal use, but I guess I could share the URL with a few people when it's completed. Anyway, I have a login / register system set up, linked to a MySQL database. I have the following columns in a table called 'users'.
userid, username, firstname, lastname, password
Before I attempt anything too stupid, I wanted somebody to give an opinion on what I am about to attempt...
I thought I could write some PHP that creates a table for each new user when they sign up. It would contain all their subjects for each day of the week, and once they input their data it would write it to the database and they wouldn't have to edit their information unless they had to (subject change, etc...)
Would a whole new table for each user's subject data be efficient? The data would have two dimensions: The day of the week (x axis) and the periods of the school day where the subjects are situated (periods 1-6 for my school)
Anyway, thanks for reading, opinions on the best way to go around doing this would be helpful. Thank you.
EDIT: Strawberry's suggestion
userid,day,period,subjectid
1 1 1 4
1 1 2 2
1 1 3 5
1 1 4 3
1 1 5 1
1 1 6 7
2 1 1 4
2 1 2 2
2 1 3 5
2 1 4 3
2 1 5 1
2 1 6 7
Here is my 2 mysql tables. In clients table is showing user connection date and in clients_pay_bill table showing in which month user is paid his/her bill from connection date (conn_date).
a) clients
clients_id conn_date
=======================
1 2016-06-01
2 2016-07-17
3 2016-06-22
4 2016-09-03
b) clients_pay_bill
cpp_id clients_id paid_month
===================================
1 1 2016-07-03
2 2 2016-07-22
3 4 2016-09-09
4 2 2016-07-22
Now I want to show all months with number of days and months of which clients is not paid until current date.
For example :
clients_id = 1 connection date (conn_date) is 2016-06-01 and he only paid 2016-07-03 month bill till now. So the sql query will be output following months:
2016-06
2016-08
2016-09
**2016-07 will not print because he already paid this months bill**
and I also want to show number of days and months e.g: 3 months some days..
I can't imagine how the sql query should look like ?
I will suggest you a bit different approach cause this one will kill you both logically and performance speaking. The way it should be done is to have records genreated in clients_pay_bill not when someone pays but when he/she should pay and as an addition to it there should be 2 columns: due_date and paid_date. So your table would look like this:
cpp_id clients_id due_month paid_month
====================================================
1 1 2016-06-03 NULL
1 1 2016-07-03 2016-07-03
1 1 2016-08-03 NULL
2 2 2016-09-22 NULL
3 4 2016-09-09 NULL
4 2 2016-07-22 NULL
You could generate monthly due note via cron or if you prefer to stay in SQL than via events. After that you have simple query selecting which due note has NULL in paid_month cause if payment was done than you would update paid_month column.
Regarding days I am not sure what effect you would like to achieve (example would help) but having list of due notes it's already half way to make calculations regarding amount of days on these records (eg. with DATEDIFF)
I've got a table with 3 separate scores in 3 separate fields:
User / Score 1 / Score 2 / Score 3
Person 1: 10 21 7
Person 2: 17 4 20
Person 3: 1 5 22
Is there a mysql command that will effectively sort each person out by the highest score from the 3 fields.
So here I need it to return:
Person 3: 1 5 22
Person 1: 10 21 8
Person 2: 17 4 20
The only way I can think of doing it would be to put them in an array, check each number for each person against each other to find the highest, then sort them into a different array.
This seems very long-winded and labour intensive though.
Add order by greatest(score1,score2,score3) desc
Manual for GREATEST()
I have a problem trying to apply rules about direct matches in a football[soccer] app. I have read this tread and it was very heplful on creating the standing positions table by the points criteria, difference and scored goals.
But i would like to know if is possible to order the teams position by direct matches:
look this positions table:
Pos Team Pld W D L F A GD Pts
1 FC Barcelona 5 2 3 0 8 5 3 9
2 **Inter Milan** 6 2 2 2 11 10 1 8
3 *Real Madrid* 6 2 2 2 8 8 0 8
4 AC Milan 5 0 3 2 8 12 -4 3
As you may see Inter Milan and Real Madrid are tied by points, and the Inter is heading real madrid because its goal difference. The result that i want to get is this :
Pos Team Pld W D L F A GD Pts
1 FC Barcelona 5 2 3 0 8 5 3 9
2 **Real Madrid** 6 2 2 2 8 8 0 8
3 *Inter Milan* 6 2 2 2 11 10 1 8
4 AC Milan 5 0 3 2 8 12 -4 3
Notice that in this time the real madrid is in front the inter milan because it won the two direct matches between them.
i have a table for teams and other for the results.
I would like to achive this using a query in mysql if is possible. Or maybe it would be better if i do this ordering on the server side (PHP).
Thanks any help would be appreciated.
It is impossible to efficiently do what you request in a single query that would return the results you ask for and sort the ties in points with that criteria.
The reasoning is simple: lets assume that you could get a column in your query that would provide or help with the kind of sorting you want. That is to say, it would order teams that are tied in points according to which one has more victories over the others (as this is very likely to happen to more than 2 teams). To make that calculation by hand you would need a double-entry table that shows the amount of matches won between those teams as follows:
| TeamA | TeamB | TeamC
------------------------------
TeamA | 0 | XAB | XAC
TeamB | XBA | 0 | XBC
TeamC | XCA | XCB | 0
So you would just add up each column row and sorting in descending order would provide you the needed data.
The problem is that you don't know which teams are tied before you actually get the data. So creating that column for the general case would mean you need to create the whole table of every team against every team (which is no small task); and then you need to add the logic to the query to only add up the columns of a team against those that are tied with it in points... for which you need the original result set (that you should be creating with the same query anyhow).
It may be possible to get that information in a single query, but it will surely be way too heavy on the DB. You're better off adding that logic in code afterwards getting the data you know you will need (getting the amount of games won by TeamA against TeamB or TeamC is not too complicated). You would still need to be careful about how you build that query and how many you run; after all, during the first few games of a league you will have lots of teams tied up against each other so getting the data will effectively be the same as building the whole double-entry table I used as an example before for all teams against all teams.
create temporary in a stored procedure and call to procedure...
create temporary table tab1 (position int not null auto_increment ,
team_name varchar(200),
points int,
goal_pt int,
primary key(position));
insert into tab1(team_name,
points,
goal_pt)
select team_name,
points,
goal_pt
from team
order by points desc,
goal_pt desc ;
For the sake of simplicity, let's assume the following tables exist:
Table 1 - List of Sellers
ID | Parent_ID | Percentage
----------------------------
1 | - | .5
2 | 1 | .4
3 | 2 | .3
This table shows 3 sellers. 1, the main parent, 2, an individual with parent 1 and 3 with parent 2 and super-parent 1. ID 1 gets a 50% commission on all individual sales PLUS the difference in commission for any subagents between their percentage levels.
For example:
The following table would represent a list of sales by Agent:
Table 2 - Sales by Agent
ID | Cost
-------------
2 | 10.00
2 | 5.00
3 | 9.00
In this scenario:
Seller ID 3 would earn 30% of his sale, or $2.70
Seller ID 2 would earn 40% of his/her sales (.4 * $5) + (.4 * $10) = $6 PLUS override on his/her child. In this case, he/she earns the difference in commissions plus the amount of the sale (.4 - .3) * $9.00 = $0.90 so Seller ID 2 would earn $6.90 total.
Seller ID 1 had no individual sales but earns override on his/her child and all subsequents: (.5-.4)(10.00) + (.5-.4)(5.00) + (.5-.4)*(9.00) = $2.40
The super parent (ID 1 in this case) could have been the direct parent of ID 3 and earned (.5-.3). This is to say, the parent child relationship is not always linear and there is no set depth to where the hierarchy lay.
Ultimately, I am trying to develop a mysql or php (or combo) formula to determine the what each seller is due in the scenario above. Calculating the total of sales for each seller and the individual seller earnings based on those sales is easy. Figuring out how to apply earning to ID 1 and 2 based on 3's production is another story.
Any prior experience in this area?
Unfortunately, MySQL doesn't make trees easy.
MSSQL has something called common table expressions that make this easier.
With MySQL, the best solution is to use a recursive stored procedure. But those can be very difficult to get right.
Instead, I would suggest having another table that stores all the parents of a child and how many levels above they are. This complicates your insertion and deletion code since this table needs to be kept up to date (triggers can help), but it will make your calculations much easier.