Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have a database with these tables
users(name, team_id, overall_user_score)
teams(id, name, team_score, totalscore)
How would I make a trigger to run after each update where its takes the score of all users in a team and the team_score of that team and add them together and puts it into totalscore.
I dont have any code for a trigger . I have the php to show the overall score and thats about it .
function showTeamScore() {
require "connect.php";
$score = mysqli_query($connection, "SELECT *
FROM teams
WHERE id = '".$_GET['id']."'") or die(mysqli_error($connection));
while ($data = mysqli_fetch_array($score)) {
echo $data['overall_score'];
}
}
Edit : Code and Problem update
mysqli_query($connection, "UPDATE teams SET totalscore=overall_score+IFNULL((SELECT sum(overall_user_score) FROM users WHERE team_id=id),0)") or die(mysqli_error($connection));
A simple subquery might do the trick:
-- query #1
SELECT id, tname,
(SELECT sum(uscore) FROM usr WHERE tid=id) tscore
FROM teams ORDER BY id
You can either run this select directly or define a view for it.
If you just want the total score you can simply do:
-- query #2
SELECT SUM(uscore) total_score FROM usr
Or, in combination with the previous team-list:
-- query #3 (combination of #1 and #2)
SELECT id, tname,(SELECT sum(uscore) FROM usr WHERE tid=id) tscore
FROM teams
UNION ALL
SELECT 999,'total score all teams',SUM(uscore) FROM usr
ORDER BY id
With sample data like - Demo, see here: http://www.sqlfiddle.com/#!9/9ba5b/4
teams:
id tname
1 Dallas
2 Houston
3 Austin
usr:
uid name tid uscore
1 Paul 1 10
2 Mary 1 3
3 Harry 2 7
4 Frank 2 4
5 Lisa 1 15
You would get this result from query #3:
id tname tscore
1 Dallas 28
2 Houston 11
3 Austin
999 total score all teams 39
OK, if you want to see all users with their respective team score in the last column you can do
-- query #4
SELECT uid, name,uscore,(SELECT sum(uscore) FROM usr WHERE tid=u.tid) tuscore
FROM usr u
which will result in
uid name uscore tuscore
1 Paul 10 28
2 Mary 3 28
3 Harry 7 11
4 Frank 4 11
5 Lisa 15 28
completely new answer:
You will probably need an update like this one (choose #4a or #4b):
-- query #4a
UPDATE teams t INNER JOIN
(SELECT tid, SUM(uscore) usc FROM usr GROUP BY tid) u ON u.tid=t.id
SET t.tsc=t.tsc+u.usc
or (see here http://www.sqlfiddle.com/#!9/040b2/1 ) :
-- query #4b (alternative version)
UPDATE teams SET tsc=tsc+IFNULL((SELECT sum(uscore) FROM usr WHERE tid=id),0)
-- IFNULL avoids the result to become NULL if there are no new contributions
Where the individual user contributions uscore will be added to the team total score tsc. It makes sense to have only one score column in teams.
With previous scores of
id tname tsc
1 Dallas 20
2 Houston 7
3 Austin 18
and the above listed user contributions the new total team scores will then be
id tname tsc
1 Dallas 48
2 Houston 18
3 Austin 18
After that the user scores should be reset to avoid a double counting. Do
UPDATE usr SET uscore=0
(Alternatively you could set an "invalidation-flag" in the user table, if you still want to be able to see the last score but not count it again.)
Related
I have a table of qualification records that I need to be able to search through, showing only the user_ids that contain all of the course codes AB, CB and DE. I've tried group by, count(*) and having but no matter how I arrange things I still do not get the desired result.
record_id user_id course_code
------------------------------------------------
1 1000 AB
2 1000 CB
3 1000 DE
4 1001 AB
5 1002 AB
6 1003 AB
7 1004 AB
8 1005 AB
9 1005 CB
10 1005 DE
Running the query I'm trying to achieve should return only user_id's 1000 and 1005.
To add extra complexity, this list of qualifications to search will be dynamically generated by a PHP script based on some user input. So on some occasions may include 10 course_code values and in others only 1.
You can use aggregation, and filter with a having clause:
select user_id
from mytable
where course_code in ('AB', 'CB', 'DE')
group by user_id
having count(*) = 3
This assumes that (user_id, course_code) tuples are unique across the tables, otherwise you would need to change the having clause to:
having count(distinct course_code) = 3
You can easily change the where and having clauses to handle more course_codes.
I'm creating a basic notification system to alert an user, that the users he follows have created a new post.
Users
id_user | name
1 Max
2 Joe
3 Ed
4 Tommy
Posts
id_post | id_user_post | posts
1 2 hi
2 2 hello
3 2 how are you
4 3 hey you
5 2 how long
6 1 whats up
7 2 come on
Community
id_follower id_followed
3 2
3 1
4 2
In this case Ed (user 3) follows to Joe (2) and Max (1), they both, have posted 6 posts.
SELECT COUNT(*)
FROM community c
LEFT JOIN posts p ON p.id_user_post=c.id_followed
WHERE c.id_follower=3
Here is how it looked like in the page
Homepage header
You have (6 new posts) > [click here to see]
My problem is how do I turn off the notification alert (6 new posts) after clicking on the it?
Do I need to create a notifications table? Should I need to add an status field to the post?
Do I need to make an Sql query again? Otherwise that notification is going to appear forever.
You should add a last_post_id column to the community table. Then you can count only the posts whose ID is higher than this.
SELECT COUNT(*)
FROM community c
LEFT JOIN posts p ON p.id_user_post=c.id_followed AND p.id_post > c.last_post_id
WHERE c.id_follower=3
Whenever you show the status to a user, you update the last_post_id to the highest ID:
UPDATE community AS c
JOIN (SELECT id_user_post, MAX(id_post) AS id_post
FROM posts
GROUP BY id_user_post) AS p ON p.id_user_post=c.id_followed
SET c.last_post_id = p.id_post
WHERE c.id_follower = 3
Ok hopefully my last post regarding the movie rating system I am trying to program. Thanks to user Asaph for helping me with my top 5 goring films. This is my database layout:
ID | UserID | Rating | TMDB | TYPE
-----------------------------------
1 34 6 432 2
-----------------------------------
2 34 9 432 3
-----------------------------------
3 44 9 468 2
and using this sql I can list the top gorey films (type 2)
sql SELECT `tmdb`, AVG(rating) AS avg_rating
FROM `tbl_rating`
WHERE `type`= :type
GROUP BY `tmdb`
ORDER BY avg_rating DESC
LIMIT 5
Now I was wondering is there a way I can make this more fair on my movie results?
for example movie123 might have 5 votes with an avg vote 7 and movie456 might only have 1 vote but if its above 7 it will be on the top of the list. How can i make this more fair? maybe somehow doing a min number of rows in group? or any other way?
Again any help is amazing!
Ok I think this is what I wanted to do :)
$sql = 'SELECT `tmdb`, AVG(rate) AS avg_rating, COUNT(rate) AS min_count FROM `tbl_rating` WHERE `type`= :type GROUP BY `tmdb` HAVING min_count > 1 ORDER BY avg_rating DESC LIMIT 5';
this seems to do the trick if there is a better way feel free to let me know :)
I could not find an answer by searching as I am not sure what exactly it would be called what I'm searching for.
Anyways, I have multiple tables in MySQL and am trying to "fill in" some of the final product.
myTable
id assigned_to location
1 2 3
2 2 3
3 3 3
myUsers
id name
1 John
2 David
3 Sally
myLocation
id name
1 SAT
2 DEN
3 AUS
Basically the end product should pull the "myTable" data and fill into a table (which I already know how to do) the name and location of each row/column so that it states something alongm the lines of
ID Assigned To Location
1 David SAT
Instead of
ID Assigned To Location
1 2 2
This should produce the expected result:
SELECT mt.id, mu.name, ml.name
FROM mytable mt JOINT myUsers mu ON mt.assigned_to = mu.id
JOIN myLocation ml ON mt.location = ml.id
I have created a database and website that will be used by football managers to select their team etc. Once a match has been completed events will be stored in the match_players table. Such events are Goal, Yellow Card, Red Card etc. I have no problem getting this information into php from SQL db.
I need to add up how many times a Goal appears (a '1' is placed in the SQL table) and for what team so that a final score can be displayed. So, for example, if Team A has 1 goal and Team B has 2 then I need to display that. I am trying to count the amount of times that a Goal is registered in the table. Any help will be greatly appreciated.
You can use MYSQL SUM
select SUM(Goal) from match_players where Team="A"
Or you can get the same for all teams by
select Team,SUM(Goal) from match_players group by Team
Why don't you demand this sum to SQL directly?
SELECT SUM(goals)
FROM match_table
WHERE team = 'Barcellona'
This should be much faster also than elaborate all data at "php-level"
If you want this detail for all teams
SELECT team,SUM(goals)
FROM match_table
GROUP BY team
Well if you store a 1 each time a goal is scored, your table looks like this:
TeamID goal
1 1
2 1
1 1
3 1
2 1
2 1
1 1
So you just want a count of how many times a team appears in that table:
select TeamID, count(*) from table group by TeamID
Will give you
TeamID | count(*)
1 | 3
2 | 3
3 | 1