For a forum i want to fetch a forumTopic with additional, linked information like the lastPostDate, lastPostUserName and starterUserName.
The problem arises with the lastPostUserName and starterUserName. When a forumTopic has only one linked post it seems to work correctly and both the lastPostUserName as the starterUserName are filled. When there are multiple posts linked to a topic only the starterUserName is filled and the lastPostUserName is NULL
The structure of the database is a formCategory has a number of formTopic the forumTopic has a number of forumPost and a forumPost is linked to a user.
SELECT forumTopic.*,
COUNT( forumPost.id ) AS postCount,
MAX(forumPost.date) AS lastPostDate,
(SELECT name FROM user AS u1 WHERE u1.id = forumPost.posterUserId AND forumPost.date = MAX(forumPost.date) )
AS lastPostUserName,
(SELECT name FROM user AS u2 WHERE u2.id = forumPost.posterUserId AND forumPost.date = MIN(forumPost.date) )
AS starterUserName
FROM forumCategory
LEFT JOIN forumTopic ON forumCategory.id = forumTopic.forumCategoryId
LEFT JOIN forumPost ON forumPost.forumTopicId = forumTopic.id
WHERE forumCategory.rewrittenName='someforumcategory'
AND forumCategory.active='Y'
AND forumTopic.active='Y'
AND forumPost.active='Y'
GROUP BY forumTopic.id
ORDER BY forumPost.date ASC
Try this
SELECT forumTopic.*,
innerv.*,
(SELECT name FROM user AS u1 WHERE u1.id = innerv.first_user)
AS startedUserName,
(SELECT name FROM user AS u2 WHERE u2.id = innerv.last_user )
AS lastUserName
FROM forumTopic
LEFT JOIN forumCategory ON forumCategory.id = forumTopic.forumCategoryId
LEFT JOIN (
SELECT forumTopicId, MAX(date) AS LAST_POSTED_dATE, MIN(date) as FIRST_POSTED_DATE,
SUBSTRING_INDEX(
GROUP_CONCAT(posterUserId ORDER BY date),
',',
1
) as first_user,
SUBSTRING_INDEX(
GROUP_CONCAT(posterUserId ORDER BY date),
',',
-1
) as last_user, count(1) as posts_under_topic
FROM forumPost where forumPost.active='Y'
GROUP BY forumTopicId ) innerv ON innerv.forumTopicId = forumTopic.id
WHERE forumCategory.rewrittenName='someforumcategory'
AND forumCategory.active='Y'
AND forumTopic.active='Y'
The subquery (innerv) filter active records and groups the records in the forumPost by topicId.
Related
How can I get combined order by results retrieved from these two queries joined by a UNION?
SELECT u.id, u.name, u.gender, n.user, n.other_user, n.type, n.notification, n.membership, n.link, n.created_at, p.photo FROM notifications n
INNER JOIN users u ON
CASE
WHEN n.user = :me THEN u.id = n.other_user
WHEN n.other_user = :me THEN u.id = n.user
END
LEFT JOIN photos p ON
CASE
WHEN n.user = :me THEN p.user = n.other_user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.other_user)
WHEN n.other_user = :me THEN p.user = n.user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.user)
END
UNION
SELECT '', '', '', '', '', '', n.notification, n.membership, n.link, n.created_at, '' FROM notifications n WHERE type = 'admin'
I want the returned records to be sorted in descending order as per their ids. For example, if the records returned from first query are 3,5,4,6,7 and from second query are 2,1,9 then all the records should be combined sorted like this 9,7,6,5,4,3,2,1.
I have tried this:
SELECT * FROM
(
*THE WHOLE QUERY ABOVE*
) AS x
ORDER BY x.id
This is not returning correct results. It is sorting the results from first query in descending order 7,6,5,4,3 and results from the 2nd query in ascending order 1,2,9. They are getting sorted individually instead of getting sorted together. How can I get them sorted combined together for 9,7,6,5,4,3,2,1.
Add notification id in both the queries and give them aliases as you haven't used aliases in your tables (I guess). Then just order by using the alias of the notification id as answered by "Thorsten Kettner".
SELECT u.id as uid, n.id as nid, u.name, u.gender, n.user, n.other_user, n.type, n.notification, n.membership, n.link, n.created_at, p.photo FROM notifications n
INNER JOIN users u ON
CASE
WHEN n.user = :me THEN u.id = n.other_user
WHEN n.other_user = :me THEN u.id = n.user
END
LEFT JOIN photos p ON
CASE
WHEN n.user = :me THEN p.user = n.other_user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.other_user)
WHEN n.other_user = :me THEN p.user = n.user AND p.order_index = (SELECT MIN(order_index) FROM photos WHERE user = n.user)
END
UNION
SELECT '', n.id as nid, '', '', '', '', '', n.notification, n.membership, n.link, n.created_at, '' FROM notifications n WHERE type = 'admin'
ORDER BY nid DESC
You have already found the issue yourself; you confused user ID and notification ID. So select the two, use alias names that tell which is which and sort:
select u.id as user_id, ..., n.id as notification_id, ...
from ...
union all
select ... from ...
order by notification_id;
I have a problem with one of my SQL request which does not return me the same thing when I work on localhost and when I work in prod environment. Could you tell me what's wrong with it?
I want to retrieve all the users contacted by one user order by the latest sent or received message.
SELECT member_id AS id, username, profile_picture, creation_date
FROM (SELECT sender_id AS member_id, username, profile_picture, messages.creation_date
FROM project_5_messages AS messages
INNER JOIN project_5_users_parameters AS users_parameters ON users_parameters.id = messages.sender_id
INNER JOIN project_5_users_profiles AS users_profiles ON users_parameters.id = users_profiles.user_id
WHERE recipient_id = :user_id AND messages.creation_date = (SELECT MAX(messages2.creation_date)
FROM project_5_messages AS messages2
WHERE messages2.sender_id = messages.sender_id)
UNION ALL
SELECT recipient_id AS member_id, username, profile_picture, messages.creation_date
FROM project_5_messages AS messages
INNER JOIN project_5_users_parameters as users_parameters ON users_parameters.id = messages.recipient_id
INNER JOIN project_5_users_profiles AS users_profiles ON users_parameters.id = users_profiles.user_id
WHERE sender_id = :user_id AND messages.creation_date = (SELECT MAX(messages2.creation_date)
FROM project_5_messages AS messages2
WHERE messages2.recipient_id = messages.recipient_id))
AS members_contacted
WHERE creation_date = (SELECT MAX(messages2.creation_date)
FROM project_5_messages AS messages2
WHERE (messages2.recipient_id = members_contacted.member_id OR messages2.sender_id = members_contacted.member_id))
ORDER BY members_contacted.creation_date DESC
Thank you in advance for your help !
The query which I am using now is below:
select ur.uid
, ua.user_activity_min_budget
, ua.user_activity_max_budget
, ua.user_activity_bedroom
, ptm.property_type_description
, cm.city_name
, lm.locality_name
, ua.user_activity_datetime
from user_registration ur
join ksl_user_activity ua
on ua.registered_user_uid = ur.uid
and ua.user_activity_uid = ( select max(ua0.user_activity_uid) from ksl_user_activity ua0)
join ksl_locality_master lm
on lm.locality_uid = ua.user_activity_area
join ksl_city_master cm
on cm.city_uid = lm.city_uid
join ksl_property_type_master ptm
on ptm. property_type_uid = ua.user_activity_property_type
where date(ua.user_activity_datet±me) >= '20l7-07-24'
and (lm.city_uid = 1 or lm.city_uid=2)
order
by ur.uid
The raw output s as this image shows:
The data is what I get now but I want the latest entry for uid 3,15,33
The reason why I have done the below is and ua.user_activity_uid=(select max(ua0.user_activity_uid) from user_activity ua0).
ksl_user_activity table has a primary key user_activity_id which has the maximum value for the latest entry but I am not getting any data when I include this in my query.
I also tried and ua.user_activity_uid=(select ua0.user_activity_uid from user_activity ua0 order by ua0.user_activity_uid desc limit 1)
This is also not working.
use max() function and sub-query
select t1.uid from user_activity t1
inner join
(select uid,max(user_activity_datetime) as user_activity_datetime from user_activity group by uid
) as t2 on
t1.user_activity_datetime=t2.user_activity_datetime
and t1.uid=t2.uid
I have a mysql select statement as below:-
select user.username, chat.from_user,chat.to_user,chat.message,chat.date_created
from chat join user on (chat.from_user or chat.to_user) in (user.user_id)
where(chat.from_user = 3 or chat.to_user = 3) and chat.chat_id IN
(SELECT distinct (MAX(chat.chat_id) )
FROM chat GROUP BY chat_group_id);
and here is my result
I always get username = admin. My expectation result is username will get correct from / to user.
Please help. Thank you.
SELECT
IF(chat.from_user=3, to_user
, IF(chat.to_user=3, form_user, 0)) AS username,
chat.from_user,chat.to_user,chat.message,chat.date_created
FROM chat
LEFT JOIN user fr_user ON chat.from_user = user.user_id
LEFT JOIN user to_user ON chat.to_user = user.user_id -- since you only want to show the TO_USERNAME, you can remove above line
WHERE (chat.from_user = 3 OR chat.to_user = 3) and chat.chat_id
IN
(SELECT distinct (MAX(chat.chat_id) )
FROM chat GROUP BY chat_group_id);
I think you intend:
select u.username, c.from_user, c.to_user, chat.message, c.date_created
from chat c join
user u
on u.user_id in (c.from_user, c.to_user)
where 3 in (c.from_user, c.to_user) and
c.chat_id in (select max(c2.chat_id)
from chat c2
group by chat_group_id
);
I have a many to many relationship. Projects table, projects_users table, and users table. I am trying to return a listing of projects, with its associated users. Here is the query I'm using, which works, but only shows a single user, when I know there should be more:
SELECT
projects.id,
`projects`.`project_name`,
( GROUP_CONCAT(DISTINCT `users`.`name` separator ', ' ) ) AS staff,
FROM `projects`
INNER JOIN `projects_users` ON (`projects_users`.`project_id` = `projects`.`id` )
INNER JOIN `users` ON (`users`.`id` = `projects_users`.`user_id` )
GROUP BY projects.id, `projects_users`.`user_id`
HAVING (`projects_users`.`user_id` = 8)
There are several users associated with each project and I would expect to return something like "User 1, User 2, User 3". Instead, I only get "User 1."
Since you need to aggregate the users per project, you should group according to the user_id:
SELECT
projects.id,
`projects`.`project_name`,
( GROUP_CONCAT(DISTINCT `users`.`name` separator ', ' ) ) AS staff
FROM projects -- was missing in the OP
INNER JOIN `projects_users` ON (`projects_users`.`project_id` = `projects`.`id` )
INNER JOIN `users` ON (`users`.`id` = `projects_users`.`user_id` )
GROUP BY projects.id -- Group by fixed here
HAVING (`projects_users`.`user_id` = 8)