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 ;
Related
i am having a problem, i am not that good in logic, so i am trying to do this by just using queries only,
i have a list of data, where i need to get their ranking, but the problem is, i need to get the first two upper to me and the last two who is lower to me.
for example
id| name | score
1 bob 20
2 anna 10
3 jose 30
4 boni 30
5 lea 100
6 leo 10
7 qwertina 90
8 josh 50
9 king 40
10 queen 10
imagine that my id value as a user is 7
so if i log in and my id is 7
i need to get the output of
id| name | score
5 lea 100
6 leo 10
7 qwertina 90
8 josh 50
9 king 40
is this possible in mysql query? any help would be really appreciated, i am really stuck with this problem.
You seem to base your logic on id's which is quite strange but here we are :
SELECT id, name, score
FROM yourTable
WHERE id BETWEEN yourId-2 AND yourId+2
Not sure of a MySQL only solution, but in pseudo php code
Grab records ordered by score
set a counter at 0
for loop starting 0, <= count of results
if the id your id?
if the loop index < 3 ? // there aren't two people ahead of you
return rows 0 to 4
elseif the loop index > count -3 ? // you are one of the last
return rows count -4 to count
else
return rows index -2 to index + 2 // you have 2 above and below you
Try that and if you get stuck post your PHP
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.
This question already has an answer here:
MYSQL/PHP find the most common item associate with a given item
(1 answer)
Closed 6 years ago.
I have a dataset of "collections" or let's call them groups or wishlists...
a collection is a list of items
collectionId | itemdId
---------------------------------
123 | 2345
123 | 3465
123 | 876
123 | 567
123 | 980
777 | 980
777 | 332
777 | 3465
777 | 876
777 | 678
777 | 567
you see item 876 and 980, are included in both collections (777 and 123) so they are a popular couple/pair
my users generate these collection, and I'm curious to extract two insights:
which are the most common items (this is easy)
which are the most common pairs/couple (or more than 2) of items (this is my question)
eg.
say many wish-lists contains iphones and a pink iphone covers
among other accessories but i want to extract in fact that iphone +
that pink iphone cover is a common recurring "couple"
all in all, basically i'm trying to do what Amazon does, if you see an iphone i want to suggest you a pink iphone cover because many other users have suggested/favorited that
Do I have to compare similarity between collection first? to see who many items they have in common? than rate the similarity with an index?
what is the best approach to this with mysql.
do i need PHP as well?
UPDATE:
in PHP I would probably do something loopy like in pseudo code
for total number of collection:
select all item from collection 1
select all item from collection 2
do array_interesct (c1,c2)
store the matching items
repeat...
select all item from collection 2
do array_interesct (c1,c3)
store the matching items
repeat...
...then elect all item from collection 2 and repeat all the iterations..
For two collection you can do a join
select a.itemID
from my_table a
join my_table b on a.itemID = b.ItemID
where a.collection = 123
and b.collection = 777
for all you can try with a cartesian product (for pair two table) .. for ( 3 ..3)
select a.itemID
from my_table a
cross join my_table b
where a.item = b.item
and a.collection <> b.collection
Through some queries and math, I have come to the point of gathering the total wages per employee on a given schedule. Each employee is assigned to a group, and now I'm trying to get total wages by group.
The table we're working with is called "schedules" and looks like:
SCH_ID | EMP_ID | GROUP_ID
55 | 1 | 7
55 | 2 | 7
55 | 3 | 8
So now I am staring at the data:
1 45.00
2 120.35
3 80.25
With 1,2,3 being the employee number and the amount of their wages to the right.
What I'm trying to accomplish is :
7 165.35
8 80.25
With 7,8 being the group numbers and the amount of total wages for that group. Maybe I have to join 2 queries or something, I dont know.
The queries and roundabout ways I've gotten to this point are sort of complicated so I hope this is enough information to help me come up with a way to do this... Any help would be greatly appreciated!
You can pull this off by using a quick JOIN and a GROUP BY operator on GROUP_ID. Something like so...
SELECT
schedules.GROUP_ID,
SUM(employees.wages) AS total_wages
FROM schedules
INNER JOIN employees
ON schedules.EMP_ID = employees.EMP_ID
WHERE
schedules.SCH_ID = 55
GROUP BY
schedules.GROUP_ID
Earlier I asked this question, which basically asked how to list 10 winners in a table with many winners, according to their points.
This was answered.
Now I'm looking to search for a given winner X in the table, and find out what position he is in, when the table is ordered by points.
For example, if this is the table:
Winners:
NAME:____|__POINTS:
Winner1 | 1241
Winner2 | 1199
Sally | 1000
Winner4 | 900
Winner5 | 889
Winner6 | 700
Winner7 | 667
Jacob | 623
Winner9 | 622
Winner10 | 605
Winner11 | 600
Winner12 | 586
Thomas | 455
Pamela | 434
Winner15 | 411
Winner16 | 410
These are possible inputs and outputs for what I want to do:
Query: "Sally", "Winner12", "Pamela", "Jacob"
Output: 3 12 14 623
How can I do this? Is it possible, using only a MySQL statement? Or do I need PHP as well?
This is the kind of thing I want:
WHEREIS FROM Winners WHERE Name='Sally' LIMIT 1
Ideas?
Edit - NOTE: You do not have to deal with the situation where two Winners have the same Points (assume for simplicity's sake that this does not happen).
I think this will get you the desired result. Note that i properly handles cases where the targeted winner is tied for points with another winner. (Both get the same postion).
SELECT COUNT(*) + 1 AS Position
FROM myTable
WHERE Points > (SELECT Points FROM myTable WHERE Winner = 'Sally')
Edit:
I'd like to "plug" Ignacio Vazquez-Abrams' answer which, in several ways, is better than the above.
For example, it allows listing all (or several) winners and their current position.
Another advantage is that it allows expressing a more complicated condition to indicate that a given player is ahead of another (see below). Reading incrediman's comment to the effect that there will not be "ties" prompted me to look into this; the query can be slightly modified as follow to handle the situation when players have same number of points (such players would formerly have been given the same Position value, now the position value is further tied to their relative Start values).
SELECT w1.name, (
SELECT COUNT(*)
FROM winners AS w2
WHERE (w2.points > w1.points)
OR (W2.points = W1.points AND W2.Start < W1.Start) -- Extra cond. to avoid ties.
)+1 AS rank
FROM winners AS w1
-- WHERE W1.name = 'Sally' -- optional where clause
SELECT w1.name, (
SELECT COUNT(*)
FROM winners AS w2
WHERE w2.points > w1.points
)+1 AS rank
FROM winners AS w1