mysql find recent user comments (part 2) - mysql

Cont. on mysql find recent user comments
Again, 2 tables:
create table user(
userID int auto_increment,
userName varchar(10),
userCreatedDate timestamp,
primary key(userID)
);
create table comment(
commentID int auto-increment,
userID int,
comment varchar(100),
primary key(commentID),
foreign key(userID) references user(userID)
);
This time the userCreateDate and commentID value is different from part 1.
And I want to find recent comment from the database.
My output like the following:
Here is the query that I tried:
select u.userID, max(c.commentID) as commentID, c.comment, u.userCreatedDate
from comment c
left join user u on c.userID = u.userID
group by u.userID
order by u.userCreateDate desc
However, I can't get my output.
Can someone help me?

You can do this as below and is called group wise max/min http://dev.mysql.com/doc/refman/5.7/en/example-maximum-column-group-row.html
select u.*,c.comment from user u
join comment c on c.userID = u.userID
join (
select max(commentID) as commentID,userID
from comment group by userID
)c1 on c1.commentID = c.commentID

try this query :-
select u.userID,commentID, c.comment, u.userCreatedDate
from comment c
left join user u on c.userID = u.userID
WHERE commentID=(SELECT MAX(c2.commentID)
FROM comment c2
WHERE c.userID = c2.userID)

Related

Mysql group joins same id together but still get duplicates [duplicate]

This question already has answers here:
Selecting from two tables with inner join and limit [duplicate]
(5 answers)
Closed last year.
I would like to group posts with same id. Now i get duplicate of posts based on how many comments. Which is wrong, it should group and show the latest comment and not create row for each comment
Table structure:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
myKey VARCHAR(100)
);
INSERT INTO users (name, myKey)
VALUES ("Gregor", "kx4ht"),
("Liza", "1lPxk"),
("Matt", "mP3fd"),
("Bob", "zStr5");
CREATE TABLE comments(
id INT PRIMARY KEY AUTO_INCREMENT,
post_id INT,
comment VARCHAR(255)
);
INSERT INTO comments (post_id, comment)
VALUES (1, "Hello world"),
(2, "I like iceCream"),
(1, "I like unicorns");
CREATE TABLE post(
id INT PRIMARY KEY AUTO_INCREMENT,
user_id INT,
text VARCHAR(255),
last_comment INT,
FOREIGN KEY (`last_comment`) REFERENCES `comments` (`id`)
);
INSERT INTO post (user_id, text, last_comment)
VALUES (1, "My first post", 3),
(1, "What is this?", 2);
Query:
SELECT u.name, p.text, c.comment
FROM post p
INNER JOIN users u ON (u.id = p.user_id)
INNER JOIN comments c ON (c.post_id = p.id)
WHERE (p.user_id = 1)
GROUP BY p.id, c.id;
Now
name text comment
Gregor My first post Hello world
Gregor What is this? I like iceCream
Gregor My first post I like unicorns
What i expect:
name text comment
Gregor What is this? I like iceCream
Gregor My first post I like unicorns
This should solve your issue
SELECT u.name, p.text, c.comment
FROM post p
INNER JOIN users u ON (u.id = p.user_id)
INNER JOIN
(
SELECT *
FROM comments c1
WHERE NOT EXISTS (
SELECT *
FROM comments c2
WHERE c1.post_id = c2.post_id AND
c1.id < c2.id
)
) c ON (c.post_id = p.id)
WHERE (p.user_id = 1)
GROUP BY p.id, c.id;

Referencing Two Tables in SQL DB

I'm new to SQL, how could I answer the following question? Do I use join?
Thank you so much.
What are the names and home cities for people searched for the word "drain"?
.schema is below:
CREATE TABLE `users` (
`id` INTEGER,
`name` VARCHAR,
`email` VARCHAR,
`city` VARCHAR,
`state` VARCHAR,
`last_visit` DATE,
`page_views` INTEGER,
PRIMARY KEY (`id`)
);
CREATE TABLE `search_terms` (
`id` INTEGER,
`word` VARCHAR,
PRIMARY KEY (`id`)
);
select u.name, u.city
from users u
inner join search_terms st on st.id = u.id
where st.word = 'drain'
I hope this helps.
You do need to join search_terms table with users table. I assume the search_terms.id is referencing to users.id.
Linking them both, will give us the results of the search terms for each user.
from there you can add more filters (WHERE conditions) to have more specific results.
So, to get the names and the home cities for each user you need to select name and city from users table, then join search_terms table and link id columns to know what words that each user has used in the search.
The query should be something like this :
SELECT name, city
FROM users
LEFT JOIN search_terms ON search_terms.id = users.id
WHERE
search_terms.word LIKE 'drain';
You could use a JOIN or a sub-query. Here's the basic strategy:
Get the id values that match what you're looking for
Look up any other info for those id values
.
SELECT name, city
FROM users usr
INNER JOIN search_terms stm ON usr.id = stm.id
WHERE stm.word = 'drain';
or ...
SELECT name, city
FROM users
WHERE id IN (SELECT id FROM search_terms WHERE word = 'drain');

Using IN operator with a subquery

Having the following scheme
CREATE TABLE request (
`id` int,
`classroom` varchar(255),
`school` varchar(255),
`date_of_application` datetime,
`status` varchar(100),
`user_id` bigint(20) NOT NULL
);
CREATE TABLE user (
`id` int,
`full_name` varchar(255)
);
CREATE TABLE user_schools (
`user_id` int,
`schools_string` varchar(255)
);
I need to obtain a list of requests where the status field is equal to 'pending' and where the school field is located in the list of schools associated with a user
Right now i am trying the following query
SELECT
r.id,
u.full_name,
r.date_of_application,
r.classroom
FROM
request r
inner join
user u on u.id = r.user_id
WHERE
r.school IN (
SELECT
us.schools_string
FROM
user_schools us
WHERE
us.user_id = u.id
)
AND r.status = 'pending';
I currently get the total list of requests. I understand what is failing is the subquery.
Attached a sqlfiddle to facilitate your collaboration
The result I expect are three applications where applicants are: user user, user user and another assistant user
Thanks for any idea. If there is a better solution, I thank you.
Regards
The code is doing what you are asking. If you want user/requests that are in the list, then you can use select distinct like this:
SELECT DISTINCT u.full_name, r.date_of_application
FROM request r inner join
user u
on u.id = r.user_id
WHERE r.school IN (SELECT us.schools_string
FROM user_schools us
WHERE us.user_id = u.id
) AND
r.status = 'pending';
But if you want the classroom and request id, then you are going to get your original result set (or some variation).

mysql find recent user comments

I have 2 tables: user and comment.
create table user(
userID int auto_increment,
userName varchar(10),
userCreatedDate timestamp,
primary key(userID)
);
create table comment(
commentID int auto-increment,
userID int,
comment varchar(100),
primary key(commentID),
foreign key(userID) references user(userID)
);
And I want my output like the following:
I want to find recent comment from the database:
However, I tried like this and cannot get my output:
select u.userID, c.commentID, u.userCreateDate
from comment c
left join userID u on c.userID = s.userID
order by u.userCreateDate desc
How should I modify so that I can get my output?
You don't want to order it by the userCreateDate from the user table, because that will be the same for all comments. It would have been nice for you to have a commentCreateDate but since you don't have that you can order it by the commentID.
Change
order by u.userCreateDate desc
to
order by c.commentID desc
Edited to add:
You also need to change your select to get the actual comment.
select u.userID, c.commentID, u.userCreateDate
should be
select u.userID, c.commentID, c.comment, u.userCreateDate
to get your desired output. Plus I don't think you want to include userCreateDate in the output as people could confuse that with the date the comment was written.

Get all conversations from one user in different chats MYSQL

I am working on a facebook style chat and am trying to get all the latest conversations from one user with other users.
Right now I am getting all the latest conversations but in the case that the other user has written to me. What I want to do is for example I have 2 conversations, conversation 1 is the latest I wrote into, but now I write into conversation 2, when I refresh the page conversation 2 will be first.
Now if the other person of conversation 1 writes me, if I refresh page conversation 1 will be first.
This are the 2 tables I am working with:
CREATE TABLE users (
id int(255) not null auto_increment,
username varchar(150) null,
email varchar(150) null,
password varchar(255) null,
salt varchar(255) null,
pic varchar(255) not null,
primary key(id)
) ENGINE = INNODB DEFAULT CHARSET=utf8;
CREATE TABLE chat (
id int(255) not null auto_increment,
id_us int(255) not null,
id_receptor int(255) not null,
message varchar(3000) not null,
chat_date datetime not null,
primary key (id),
index chatUsId(id_us),
index chatRecId(id_receptor),
foreign key (id_us) references users(id) on delete cascade,
foreign key (id_receptor) references users(id) on delete cascade
) ENGINE = INNODB DEFAULT CHARSET=utf8;
And this is the query I am using
SELECT m.id_us, m.id_receptor, u.username, u.pic
FROM users AS u, chat AS m
WHERE (m.id_us = u.id AND m.id_receptor =:id_us or m.id_receptor = u.id AND m.id_us =:id_us)
AND m.chat_date = (SELECT MAX( c.chat_date ) FROM chat AS c WHERE m.id_us = c.id_us AND m.id_receptor = c.id_receptor )
group by u.username
ORDER BY m.id DESC
In this case :id_us could be for example 1
I know its not correct as it is not doing what I would like it to do, but I've been struggling trying to find the way to get the results as I want, but I am stucked, any help will be apreciated.
To explain myself better, what I am trying to do is for example when you chat in facebook, the facebook messages list to view your latest conversations.
OK how about this: (using 123 for id of user1)
select T1.user2_id, users.username, users.pic, max(cdate) maxDate from
(select chat.id_receptor user2_id, max(chat_date) cdate
from chat
where chat.id_us=123
group by chat.id_receptor
union distinct
(select chat.id_us user2_id, max(chat_date) cdate
from chat where chat.id_receptor = 123
group by chat.id_us)) T1
inner join users on (users.id = T1.user2_id)
group by T1.user2_id
order by maxDate desc
I want recent message also like whatsapp, and I have update your query as per my tables.
select T1.user2_id, message, user_profile.user_name, user_profile.avatar, max(cdate) message_date from (select messages.receiver_id user2_id, messages.message, (message_date) cdate from messages where messages.sender_id=2 group by messages.receiver_id union distinct(select messages.sender_id user2_id, messages.message, max(message_date) cdate from messages where messages.receiver_id = 2 group by messages.sender_id)) T1 inner join user_profile on (user_profile.id = T1.user2_id) group by T1.user2_id order by message_date desc
Just added another SELECT + JOIN. Please refer to below and let me know if any questions, will try to answer.
I would like to note that even though the above answer is marked is correct, in my understanding it does not covers the full needs of requested query as does not display the key item - i.e. last message per each chat.
$sql="
SELECT T2.maxDate, T2.user2_id, T2.ava, T2.userName,chat.user_to,chat.user_from,chat.body,chat.viewed FROM (SELECT T1.user2_id, users.userName, users.ava, max(cdate) maxDate FROM
(SELECT chat.user_to user2_id, max(msg_time) cdate
FROM chat WHERE chat.user_from=18
GROUP BY chat.user_to
union distinct
(SELECT chat.user_from user2_id, max(msg_time) cdate
FROM chat WHERE chat.user_to=18
GROUP BY chat.user_from)) T1
inner join users on (users.userID = T1.user2_id)
group by T1.user2_id
order by maxDate desc) T2
join chat on (T2.maxDate = chat.msg_time) ORDER BY T2.maxDate DESC";