How can I summarize results of two queries below?
select firstname, surname, COUNT(*) as Built
from orders
join users on orders.builder = users.id
where bStop > 1461496211 and bStop < 1461582649
group by users.id;
select firstname, surname, COUNT(*) as Built
from production_points
join users on production_points.rewarded = users.id
where Date(datetime) = '2016-04-25'
group by users.id
Same user can be in both tables, so i want to sum his results, don't want two separate lines i.e. first one showing 4 and second one 6. Just total 10
You can use Union.
If this is mysql you can see its syntax here: http://dev.mysql.com/doc/refman/5.7/en/union.html
It is similar in the other DB vendors.
Can you maybe get the result of each and assign them to different variables.
And sum up the variables.
After research as advised by you guys, here is the solution:
select uid, firstname, surname, Count(*) as Built from (
select users.id as uid, firstname, surname from orders join users on orders.builder = users.id where bStop > 1461542400 and bStop < 1461592622
union all
select users.id as uid, firstname, surname from production_points join users on production_points.rewarded = users.id where Date(datetime) ='2016-04-25'
) performance group by uid;
Related
For a project I'm working on, I am trying to query a time clock but when I LEFT JOIN multiple many to many (or in a single users' record sense, 1 to many) it creates duplicate entries, so when it's grouped by, the aggregate totals are incorrect.
Given the below mock schema:
And a query:
SELECT
UserTbl.UserID,
CONCAT_WS(", ", UserTbl.LastName, UserTbl.FirstName) AS UserName,
SUM(TIMESTAMPDIFF(MINUTE, TimeClockTbl.StartDateTime, TimeClockTbl.EndDateTime)) AS ClockedInMinutes,
FROM
Users AS UserTbl
LEFT JOIN
TimeClock AS TimeClockTbl
ON UserTbl.UserID = TimeClockTbl.UserID
LEFT JOIN
UserRoles AS UserRoleTbl
ON UserTbl.UserID = UserRoleTbl.UserID
WHERE
UserRoleTbl.RoleID IN (1,2,3)
GROUP BY
UserTbl.UserID
ORDER BY
UserTbl.LastName ASC,
UserTbl.FirstName ASC;
If the user only has 1 role, assigned, it works fine, but if there is a second or third role assigned, it seems to multiply the final result. I considered using a GROUP_CONCAT for the roles and filtering after, but that doesn't seem to be efficient. I also considered subqueries to calculate the clocked in hours for a given user, but I felt that would have the same result. It's also important to note that this is scaled to have a TimeClock table with multiple entries, and a Scheduled table with multiple entries as well.
How can I do this with a decent amount of efficiency?
Simple decision:
SELECT UserTbl.UserID,
CONCAT_WS(", ", UserTbl.LastName, UserTbl.FirstName) AS UserName,
SUM(TIMESTAMPDIFF(MINUTE, TimeClockTbl.StartDateTime, TimeClockTbl.EndDateTime)) AS ClockedInMinutes,
FROM Users AS UserTbl
LEFT JOIN TimeClock AS TimeClockTbl ON UserTbl.UserID = TimeClockTbl.UserID
WHERE UserTbl.UserID IN( SELECT UserID FROM UserRoles WHERE RoleID IN (1,2,3) )
GROUP BY UserTbl.UserID
ORDER BY UserTbl.LastName ASC, UserTbl.FirstName ASC;
Concept for similar situations - consistent join:
SELECT A.*,
SUM(TIMESTAMPDIFF(MINUTE, TimeClockTbl.StartDateTime, TimeClockTbl.EndDateTime)) AS ClockedInMinutes,
MAX(A.RolesTitle) AS RolesTitle
FROM (
SELECT UserTbl.UserID,
CONCAT_WS(", ", UserTbl.LastName, UserTbl.FirstName) AS UserName,
FirstName, LastName,
GROUP_CONCAT(Roles.Title) as RolesTitle
FROM Users AS UserTbl
JOIN UserRoles AS UserRoleTbl ON UserTbl.UserID = UserRoleTbl.UserID
JOIN Roles ON Roles.RoleID=UserRoleTbl.RoleID
WHERE UserRoleTbl.RoleID IN (1,2,3)
GROUP BY UserTbl.UserID
) A
LEFT JOIN TimeClock AS TimeClockTbl ON A.UserID = TimeClockTbl.UserID
GROUP BY A.UserID
ORDER BY A.LastName ASC, A.FirstName ASC;
I have two tables, say Users and Interviews. One user can have multiple interview records.
Users
-----
UserID
FirstName
LastName
Interviews
----------
InterviewID
UserID
DateOfInterview
I want to get only the latest interview records. Here's my query
select u.UserID, firstname, lastname, max(DateOfInterview) as latestDOI
from users u
left join interviews i
on u.UserID = i.UserID
GROUP BY u.UserID, firstname, lastname
ORDER BY max(DateOfInterview) DESC
How do I update the query to return the InterviewID as well (i.e. the one which corresponds to max(DateOfInterview))?
Instead of using an aggregate function in your select list, you can use an aggregate subquery in your WHERE clause:
select u.UserID, firstname, lastname, i.InterviewId, DateOfInterview as latestDOI
from users u
left join interviews i
on u.UserID = i.UserID
where i.UserId is null or i.DateOfInterview = (
select max(DateOfInterview)
from interviews i2
where i2.UserId = u.UserId
)
That does suppose that max(DateOfInterview) will be unique per user, but the question has no well-defined answer otherwise. Note that the main query is no longer an aggregate query, so the constraints of such queries do not apply.
There are other ways to approach the problem, and it is worthwhile to look into them because a correlated subquery such as I present can be a performance concern. For example, you could use an inline view to generate a table of the per-user latest interview dates, and use joins to that view to connect users with the ID of their latest interview:
select u.*, im.latestDOI, i2.InterviewId
from
users u
left join (
select UserID, max(DateOfInterview) as latestDOI
from interviews i
group by UserID
) im
on u.UserId = im.UserId
left join interviews i2
on im.UserId = i2.UserId and im.latestDOI = i2.DateOfInterview
There are other alternatives, too, some standard and others DB-specific.
Rewrite to use an OUTER APPLY when grabbing your interview, that way you can use order by rather than MAX
select u.UserID, firstname, lastname, LatestInterviewDetails.ID, LatestInterviewDetails.DateOfInterview as latestDOI
from users u
OUTER APPLY (SELECT TOP 1 Id, DateOfInterview
FROM interviews
WHERE interviews.UserID = u.UserId
ORDER BY interviews.DateOfInterview DESC
) as LatestInterviewDetails
Note: This is providing you are using Microsoft SQL Server
I'm working within MySQL server and am looking to run a query for multiple userID's to return stats.
select
Firstname,
Lastname,
email,
count(distinct startTime) as "total Rounds",
MAX(starttime) as "Last Round"
from users.users
join rounds.rounds on rounds.rounds.userId = users.users.userId
where users.userid and rounds.userId ="ENTER A USER ID HERE"
Any suggestions on getting a results set for multiple users?
You can use the COUNT() function, but just use GROUP BY to get the count per user, like this:
SELECT firstName, lastName, email, COUNT(distinct startTime) AS totalRounds, MAX(startTime) AS lastRound
FROM users u JOIN rounds r ON r.userId = u.userId
GROUP BY u.userId;
This will group all rows by the individual user, count the unique start times for that user, and the latest start time, but I'm sure you understand that concept by now.
Use group by:
select Firstname, Lastname, email, count(distinct startTime) as "total Rounds",
MAX(starttime) as "Last Round"
from users.users u join
rounds.rounds r
on r.userId = u.userId
group by Firstname, Lastname, email;
Also, learn to use table aliases. They make queries easier to write and to read.
I'm generating a query where I'm getting list of userid's seprated by comma using GROUP_CONCAT. I want to count these IDs in the same query. Can I do so?
$query="SELECT id,
longitude,
latitude,
game_date,
min_player,
game_description,
is_public,
is_user_coming,
allow_player_invite,
location,
game_type,
game_status,
cdate,
ownerid,
COUNT(j.users) as joinees,
users.username
FROM games
left join
(SELECT gameid, GROUP_CONCAT(userid, ',') as users
from user_game_join where games.id=user_game_join.gameid) j on j.gameid=id
join (select id as uid,name as username from users) users on users.uid=ownerid
AND (`location` LIKE '$location%' or `location` LIKE '".ucfirst($location)."%')";
This is my query and I need to get the number of joineers. Attached herewith is the snapshot of my tables:
SELECT gameid,
GROUP_CONCAT(userid, ',') as users,
count(userid) as user_count
from user_game_join
where games.id = user_game_join.gameid
A friend of mine helped me with that. Surprisingly, I was using join in wrong place. Sharing the query just in case someone might find it helpful:
SELECT games.*,ugj.joinees,u.username FROM games JOIN
(select id as uid, name as username from users) users on users.uid = games.ownerid
AND games.id='$gid' left join
(select count(userid) as joinees,gameid as gid from user_game_join group by gameid ) ugj on games.id=ugj.gid LEFT JOIN
(select id,name as username from users) u on u.id=games.ownerid
i have 2 tables, users and follows. table follows has a column named status. I would like to count how many follows each user has grouping by the status.
The query below returns a record for each status type for each user.
SELECT users.name as user_name, f.status, count(f.id)
FROM users
JOIN application_follows f ON f.user_id = users.id
GROUP BY users.id, f.status
ORDER BY users.id
returns something like:
user_name status count
mike new 10
mike old 5
tom new 8
tom old 9
but i would like something more friendly like:
user_name status_count
mike new,10|old,5
tom new,8|old,9
tried using group_concat and count but didnt work. Any clues?
You need to use GROUP BY twice, first on (user_id, status) from follows to get counts then on user_id from joined table to concat:
SELECT users.name, GROUP_CONCAT( CONCAT(f.status, ',', f.cnt) SEPARATOR '|' )
FROM users
JOIN
( SELECT user_id, status, count(id) AS cnt
FROM application_follows
GROUP BY user_id, status ) f
ON f.user_id = users.id
GROUP BY users.id
I don't know full tables definitions so I created query, which is using only user_name, status and count.
SELECT user_name, GROUP_CONCAT(CONCAT(status, ',', count) SEPARATOR '|') FROM users GROUP BY user_name ORDER BY user_name;