How to Select max date in this query? - mysql

I would like to write a query which retrieves name, id, and last modified date for each User. The below query gives the name, id, and last modified date from tables UserDetails1 and UserDetails2.
How could I modify this query to return a single date value, the max date for a given user_id in either of the details tables?
SELECT
id,
name,
MAX(userdetails1.date_modified),
MAX(userdetails2.date_modified)
FROM User user
INNER JOIN UserDetails1 userdetails1
ON userdetails1.user_id = user.id
INNER JOIN UserDetails2 userdetails2
ON userdetails2.user_id = user.id
User
id | name
---------
1 | name1
2 | name2
3 | name3
UserDetails1
user_id | date_modified
---------------------
1 | 2016-11-28 16:28:26
....
UserDetails2
user_id | date_modified
---------------------
1 | 2016-11-29 16:29:26
....

Try this, although I think there can be a more optimized way to write it.
SELECT
id,
name,
(CASE
WHEN MAX(userdetails1.date_modified) > MAX(userdetails2.date_modified)
THEN MAX(userdetails1.date_modified)
ELSE MAX(userdetails2.date_modified)
END)
FROM User user
INNER JOIN UserDetails1 userdetails1
ON userdetails1.user_id = user.id
INNER JOIN UserDetails2 userdetails2
ON userdetails2.user_id = user.id
GROUP BY id, name

One option is to UNION your two date tables together. This can be done before or after you JOIN. I personally would UNION before JOINING as it is simpler in my mind and to write.
Please excuse the SQL Server-esque syntax.
Before JOINing:
SELECT
u.id,
u.name,
MAX(d.date_modified) last_modified
FROM [User] u
INNER JOIN
(
SELECT user_id, date_modified
FROM UserDetails1
UNION ALL
SELECT user_id, date_modified
FROM UserDetails2
) d
ON u.id = d.user_id
GROUP BY u.id, u.name
After JOINing:
SELECT
id,
name,
max(date_modified) last_modified
FROM
(
SELECT
u.id, u.name, d.date_modified
FROM [User] u
INNER JOIN UserDetails1 d
ON d.user_id = user.id
UNION ALL
SELECT
u.id, u.name, d.date_modified
FROM [User] u
INNER JOIN UserDetails2 d
ON d.user_id = u.id
)
GROUP BY id, name

Related

Count of Items Based on Todays Date in MySQL

I have 2 tables one has the user_info and another has user_activies.
I have a query that fetches several rows from user_info table. What I want to add to this query is;
I want to fetch todays user activities and count them from user_activities table.
user_info
| id | name | views | lastlogin | regdate | group_id |
user_activities
| id | userid | activity | date |
Current query
select id, name, views, lastlogin
from user_info
where group_id = 2
ORDER BY user_info.id ASC
How could I concatenate count of the total number of activities has been done today?
Thanks in advance!
i'm assuming that date is of type date:
select
u.id,
u.name,
u.views,
u.lastlogin,
sum(
-- if datetime IF (date(date) = curdate() , 1, 0)
IF (date = curdate() , 1, 0)
) as 'today_activities'
from user_info u
-- using left join you will get the list of all user even if they
-- don't have any activities today with sum activities= 0
LEFT JOIN user_activities a on u.id = a.userid
where
group_id = 2
group by u.id
ORDER BY u.id ASC
You want this:
SELECT i.id, i.name, i.views, i.lastlogin, Count(a.id)
FROM user_info i, user_activities a
WHERE i.group_id = 2 AND i.id = a.userid
AND a.date = CURDATE()
ORDER BY user_info.id ASC;
This gives you a record of every user with a count of todays activities. (You may need to change the `a.date = CURDATE()` to fit your timestamp needs)
This will not give you a list of ervery user. Instead you will have to select a single user. If you select multiple users you will get a random name with the sum of all activities from all selected users.
Or short: This does not solve your problem. Take the JOIN-solution.
you can try this:
SELECT i.id, i.name, i.views, i.lastlogin, Count(a.activities)
FROM user_info i inner join user_activities a
WHERE i.group_id = 2 AND i.id = a.userid
AND a.date = now()
ORDER BY user_info.id

Why my query shows no errors, but also returns zero rows?

I have written this query to get as many rows as there are users + count of potentials that each user have created + all potentials that have been converted. This is how it looks like:
SELECT u.*, p.allPotentials, pc.cPotentials
FROM os_user u
JOIN (SELECT FID_author, count(*) allPotentials FROM os_potential) p
ON p.FID_author = u.ID
JOIN (SELECT converted, FID_author, count(*) cPotentials FROM os_potential) pc
ON p.FID_author = u.ID AND pc.converted = 1
I am trying to do it with uncorrelated subquery as this answer explained me, that I can combine my queries into 1. But im getting 0 rows.
My tables looks like this:
Users:
+----+------+-------+
| ID | Name | Email |
+----+------+-------+
Potentials:
+----+------+-------+------------+-----------+
| ID | Name | Email | FID_author | converted |
+----+------+-------+------------+-----------+
FID_author is foreign key, the user id.
My query is returning 0 rows and shows no errors. What am I doing wrong?
EDIT
So far my query:
SELECT u.*, p.allPotentials, pc.cPotentials
FROM os_user u
LEFT JOIN (SELECT FID_author, count(*) allPotentials
FROM os_potential GROUP BY FID_author) p
ON p.FID_author = u.ID
LEFT JOIN (SELECT converted, FID_author, count(*) cPotentials
FROM os_potential GROUP BY FID_author) pc
ON p.FID_author = u.ID
AND pc.converted = 1
GROUP BY u.ID
I am getting results almost as expected, but the problem is, cPotentials contains 1 in every row, which is false. There are much many then only 1. Where could be the problem?
Missing group by on subquery and eventully use left join
SELECT u.*, p.allPotentials, pc.cPotentials
FROM os_user u
LEFT JOIN (SELECT FID_author, count(*) allPotentials FROM os_potential
GROUP BY FID_author) p
ON p.FID_author = u.ID
LEFT JOIN (SELECT converted, FID_author, count(*) cPotentials FROM os_potential
GROUP BY converted,FID_author) pc
ON pc.FID_author = u.ID AND pc.converted = 1

How to Get number of post done by user

Here is my question:
I have 4 tables which hold post done by user(say CatA,CatB,CatC and CatD, each table hold created_by column). My requirement is to get all the user available from table USER with post count (sum of post).
I am struggling to find answer from past 2 days and i'm still clueless.
Any idea is much appreciated.
SELECT u.username,
a.cnt + b.cnt + c.cnt + d.cnt AS total_posts
FROM users u
LEFT JOIN (SELECT created_by, COUNT(*) AS cnt FROM CatA GROUP BY created_by) a
ON u.id = a.created_by
LEFT JOIN (SELECT created_by, COUNT(*) AS cnt FROM CatB GROUP BY created_by) b
ON u.id = b.created_by
LEFT JOIN (SELECT created_by, COUNT(*) AS cnt FROM CatC GROUP BY created_by) c
ON u.id = c.created_by
LEFT JOIN (SELECT created_by, COUNT(*) AS cnt FROM CatD GROUP BY created_by) d
ON u.id = d.created_by
ORDER BY total_posts DESC
This return me total post count on top (irrespective of user post count) like below instead of post count for each user
username | user1 | user2 | user3
total_posts | 11020 (Total post count) | NULL | NULL | and so on
More Info:
SELECT created_by, COUNT(*) AS cnt FROM CatA GROUP BY created_by
This returns me:
created_by | 22 | 26 | 88 | 90
cnt | 6 | 20 | 15 | 8
So it seems like you have a separate table for each category (which is actually not the most optimal design by the way). What you can do to get the count of posts for all users is:
SELECT u.*,
a.cnt + b.cnt + c.cnt + d.cnt AS total_posts
FROM users u
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM CatA GROUP BY user_id) a
ON u.user_id = a.user_id
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM CatB GROUP BY user_id) b
ON u.user_id = b.user_id
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM CatC GROUP BY user_id) c
ON u.user_id = c.user_id
LEFT JOIN (SELECT user_id, COUNT(*) AS cnt FROM CatD GROUP BY user_id) d
ON u.user_id = d.user_id

Joining tables and aggregating data in MySQL?

I have 2 tables. Members and their projects. I need to extract all the users, with the number of their projects, sorted by the number of projects.
Table: users:
id | username | email | password | reg_date
Table: projects:
id | title | descr | autor
For the join:
projects.autor = users.id
SELECT
users.id,
users.username,
COUNT(projects.id) AS `num_projects`
FROM
users
LEFT OUTER JOIN
projects
ON
projects.autor = users.id
GROUP BY
users.id
ORDER BY
num_projects DESC
SELECT u.id AS id, u.username AS username, u.email AS email, u.password AS password, u.reg_date AS reg_date, COUNT(p.id) AS projects_count
FROM users u
LEFT OUTER JOIN projects p ON p.autor = u.id
GROUP BY u.id
ORDER BY projects_count DESC

Mysql queries issue

I have 3 tables in my mysql DB to query.
Users_rates (fields: id,userid,raterid,rate,eventid) containing all of the rates(rate) that have been assigned to users(userid), participating to specific events(eventid), by other users(raterid)
Events_participants (fields:id,userid,eventid) containing all of the users(userid) participating to each event(eventid)
Users (fields:id,name,lastname)containing all the user relative data
I need to query those three tables to retrieve an event-specific rank for the users' rates.
Ex. John,Erik and Mark participated to 'eventid=31'.
John received 1 rate from Mark, and 2 from Erik.
Mark received 1 rate from Erik.
Nobody has rated Erik though.
I need to retrieve for each user name,lastname and the sum of the rates received for eventid=31
I tried with this:
SELECT events_participants.userid,users.name,users.lastname,
(SELECT SUM(rate)FROM users_rates WHERE users_rates.eventid=31 AND users_rates.userid=events_participants.userid)AS rate
FROM(( events_participants INNER JOIN users ON events_participants.userid=users.id)
LEFT OUTER JOIN users_rates ON events_participants.userid=users_rates.userid )
WHERE events_participants.eventid=31
But I receive:
userid | name | lastname | rate
1 | luca | silvestro | 1
3 | claudio | buricchi | 6
3 | claudio | buricchi | 6
What's the right query?
Thanks
Luca
Try this:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users LEFT JOIN (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp USING (userid)
It might give an error, this might work instead:
SELECT users.userid, users.name, users.lastname, temp.sum as rate
FROM users, (
SELECT userid, SUM(rate) as sum FROM users_rates WHERE eventid = 31 GROUP BY userid
) as temp WHERE users.userid = temp.userid
I don't know if I got the problem right, but maybe something like:
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN users_rates AS ur ON ur.userid = u.id
WHERE ur.eventid = 31
GROUP BY u.id
edit: If you want to receive a list with all users regardless of whether they have any rates at all, you could also join the users_participants table and replace the INNER JOIN of users_rates by a LEFT JOIN. The WHERE clause has to reference events_participants then (not users_rates anymore as it could be NULL):
SELECT u.id, u.name, u.lastname, SUM(ur.rate) AS rate
FROM users AS u
INNER JOIN events_participants AS ep ON ep.userid = u.id
LEFT JOIN users_rates AS ur ON ur.userid = u.id AND ur.eventid = ep.eventid
WHERE ep.eventid = 31
GROUP BY u.id