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.
Related
When I run the following query, I only get the first row:
SELECT
u.name AS Firstname, u.lastname AS Lastname, count( DISTINCT(p.id) ) AS Count
FROM
projects p
INNER JOIN users u ON p.user_fk = u.id
order by user_fk;
I have two tables, Projects and Users and the project table has a user ID which I am using to get the name from the users table. I then want to see how many unique projects there are for each user and display the amount of projects each user has.
You need a group by:
SELECT u.name AS Firstname, u.lastname AS Lastname,
count( DISTINCT p.id ) AS Count
FROM projects p INNER JOIN
users u
ON p.user_fk = u.id
GROUP BY u.name, u.lastname
order by user_fk;
In almost any other database, your query would return an error, because it has columns in the SELECT that are not aggregated and not in the GROUP BY. I think MySQL is moving toward making that the default behavior.
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;
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;
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
List the guests by name and the number of times each has reserved a room at one of our hotels. Arrange the list in order from most-frequent to least-frequent guest.
I'm keep getting aggregate function for Firstname and LastName
So Far i have this code
SELECT FirstName, LastName, Count(ResNum) AS TotalReservations
FROM RESERVATION, GUEST
Where GUEST.GuestNo = RESERVATION.GuestNo
ORDER BY RESERVATION.GuestNo
And here is the link for the RelationShip Table
View Relationship Table <--- LINK
Try this:
SELECT FirstName, LastName, Count(ResNum) AS TotalReservations
FROM RESERVATION
INNER JOIN GUEST ON GUEST.GuestNo = RESERVATION.GuestNo
GROUP BY FirstName, LastName
ORDER BY COUNT(ResNum) DESC
SELECT g.FirstName, g.LastName, Count(r.ResNum) AS TotalReservations
FROM RESERVATION AS r
INNER JOIN GUEST AS g ON g.GuestNo = r.GuestNo
GROUP BY g.FirstName, g.LastName
ORDER BY Count(r.ResNum) DESC