select messages sent by user or to user - php

This should be fairly simple, however I am stuck with it.
when i do the query
SELECT * FROM `inbox` where toid=4 or fromid=4 order by time desc
, i get:
id toid fromid message time
23 48101 4 hello call me 12/23/2011 12:27
6 34584 4 hi there 12/22/2011 15:42
5 34584 4 how are you 12/22/2011 14:08
4 34584 4 say hello 12/22/2011 14:07
3 34584 4 whats up 12/22/2011 14:07
2 4 34584 nice picture 11/24/2010 0:00
1 4 2 this is very interesting! 12/23/2008 0:00
Now, I need to group the conversations between user 4 and other users each to one row with last message (like facebook messages do).
does anyone know the best way to do that?
Thank you!

SQL Fiddle
select i.id, toid, fromid, message, `time`
from
inbox i
inner join (
select max(id) as id
from inbox
where toid = 4 or fromid = 4
group by greatest(toid, fromid), least(toid, fromid)
) s on i.id = s.id

Related

Select rows where one value in field name occured in multiple rows

Suppose I have a database structure like this.
Table users
id name
1 Name1
2 Name2
3 Name3
4 Name4
And another table logs
id userid
1 1
2 1
3 2
4 3
5 3
6 3
7 4
8 4
9 4
Now if I enter 3 in text box and press submit then in the server side PHP I need to fetch and display records from users table with id 3 and 4 i.e., Name3 and Name4 from users table as in logs table they occurred 3 times each. Similarly, if I press 2 and submit it should fetch and display record Name1 as id 1 from users table has occurred 2 times in logs table. What should be the query here for this? I don't understand how to start with this so I cannot post what I have tried. Please help.
Try this query, it is working
select name from users where id in (select userid from logs group by userid having count(userid) = '".$inputvalue."')
DEMO LINK
Group by users and take only those groups having the count of records you input
select u.name
from users u
join logs l on l.userid = u.id
group by u.name
having count(l.id) = $inputValue
Demo
This will work for you.
Select u.name
from ( select userid,count(*) as NoOfRecords
from logs
group by userid
having count(*) = $inputvalue ) as a
inner join users u on a.userid = u.id

notifications alerts turn off sql php

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

Query database for most current message per receiver_id [duplicate]

This question already has answers here:
MySQL query, MAX() + GROUP BY
(7 answers)
Closed 6 years ago.
Here is example of my mysql query problem:
Table name: messaging
Id ad_id sender_id receiver_id message
1 2 5 1 message1
2 2 5 1 message2
3 2 5 1 message3
4 8 7 3 message4
5 2 4 2 message5
Now i would like to run a mysql query which will output results in following format:
Id ad_id sender_id receiver_id message
3 2 5 1 message3
4 8 7 3 message4
5 2 4 2 message5
Note: multiple rows with the same value in ad_id, sender_id and receiver_id should output only the last row.
I would appreciate any assistance to achieve similar output. Thanks in advance.
I suggest shortlisting the correct Ids before extracting the data, especially if you have more columns.
select Id, ad_id, sender_id, receiver_id, message
from messaging
where id in (select max(id)
from messaging
group by ad_id, sender_id, receiver_id)
You should use GROUP BY with the 3 columns you want to agroup and then use the MAX to get the last inserted row of each group (assuming the Id is auto-increment)
SELECT MAX(Id) as Id, ad_id, sender_id, receiver_id FROM messaging GROUP BY ad_id, sender_id, receiver_id;

fair rating for my current movie database

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 :)

Calculate overall score [closed]

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.)

Categories