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;
Related
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
This question already has answers here:
MySQL join with where clause
(3 answers)
Closed 5 years ago.
I have two tables
1st table :-
id name dept
1 John dept1
2 Mary dept2
3 Dave dept3
4 John dept4
5 John dept5
2nd table :-
id submitter dept
1 Rupert dept3
2 Joe dept1
3 Lisa dept2
4 Louise dept4
5 Tom dept5
what i would like is a query to allow people in the name column in the first table to only show records based on their matching departments eg John in table one will return the 3 records in table 2 (id 2,4 and 5)
So far i have tried SELECT * FROM table1, table2 WHERE table1.dept = table2.dept AND table1.name='John'
If I correctly understand your problem, you need to make a join between the two tables using the field dept and filter your results by the name of the requester, in the first table.
SELECT t2.submitter, t2.dept
FROM table1 t1
LEFT JOIN table2 t2 ON t1.dept = t2.dept
WHERE t1.name = :person_name
Documentation and examples (you can also look at the left menu at Inner, right, full and self join's).
This question already has answers here:
What's the difference between INNER JOIN, LEFT JOIN, RIGHT JOIN and FULL JOIN? [duplicate]
(3 answers)
Closed 8 years ago.
I have 3 tables - User table, book1 table, book2 table.
User table is like this -
user_id | gender | l_name | f_name
-------- -------- -------- -------
1 male Doe Jon
2 female Xu Jini
3 female Din Jane
book1 table -
b_id | user_id | amount | date
----- --------- -------- ----------
1 3 98.30 2014-05-14
2 1 65.70 2014-05-07
3 2 14.40 2014-05-06
4 2 55.60 2014-05-07
book2 table -
b_id | user_id | amount | date
----- --------- -------- ----------
1 2 38.20 2014-04-06
2 3 84.40 2014-04-02
3 3 31.30 2014-04-12
4 1 74.40 2014-05-06
The user gives a date range as input and I want to calculate the sales count(COUNT), total amount(SUM) and the max date(MAX) for that date range. After this I want to connect this data to the user table and get the gender and name using the user_id.
I wrote this query to get the data for the given date range from book1 and book2 tables-
SELECT * FROM book1
WHERE date between '2014-04-02' and '2014-05-15'
UNION ALL
SELECT * FROM book2
WHERE date between '2014-04-02' and '2014-05-15'
ORDER BY customer_id;
By this i get all the rows in the book1 and book2 table which satisfy the date range. Now should i use subquery or something else to reach the goal. I think sql should take care till getting the count, sum and max from book tables. Then the connection to the user table should be done in PHP. Am i on the right path? Can everything be done in SQL? I am kinda lost.
Yes, you can do it in SQL using a plain JOIN.
This will basically get all users and join them up with their respective amounts in the period. After that, the results are grouped by user so that we can sum up the amounts.
SELECT u.user_id, u.l_name, u.f_name, SUM(x.amount) `total amount`
FROM user u
JOIN (
SELECT user_id, date, amount FROM book1
UNION ALL
SELECT user_id, date, amount FROM book2
) x
ON u.user_id = x.user_id
AND x.date between '2014-04-02' and '2014-05-15'
GROUP BY u.l_name, u.f_name,u.user_id
An SQLfiddle to test with.
As a side note, learning about joins is really a necessity to work efficiently with SQL databases.
This question already has answers here:
Select most common value from a field in MySQL
(3 answers)
Closed 8 years ago.
I don't know how to phrase this, but I'm trying to get the rows with the most occurrences in the column to display, for example
ID from_id to_id
1 1 3
2 1 3
3 1 3
4 1 3
5 2 3
6 3 3
7 3 3
8 4 3
9 4 3
I'm trying to get 1,4,3 from the database because it's more frequent, how would I do this?
Sorry if it's a bad question, I don't know how to phrase it
This is quite easy, just COUNT(from_id), eg like this
SELECT from_id, COUNT(from_id) AS total FROM your_table
GROUP BY from_id
ORDER BY total DESC
You can now modify this, eg LIMIT 10 to get the top 10 or WHERE total > 1 before the GROUP BY to only get rows which occure more than once.
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