Count Function in Access SQL Query - mysql

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

Related

Running into issues with SQL Error 1111

I am creating an instance in which the customer has more than 1 reservation. To do this, each time the customer number is listed more than once in the reservation table, this signifies that they have more than one reservation (which again, is the condition). Unfortunately, when I attempt to run this query I get:
Error Code: 1111 (Invalid use of group function).
Here is what I have done below.
SELECT FirstName, LastName, tripName
FROM reservation, customer, trip
WHERE reservation.CustomerNum = customer.CustomerNum
AND reservation.TripID = trip.TripID
AND COUNT(reservation.CustomerNum) > 1
GROUP BY reservation.CustomerNum;
I am very new to SQL, any advice will be very helpful.
You need to write proper joins, using aliases helps keep things readable and saves you extra keystrokes, and you would need to use something like this to limit your results to those with more than one reservation:
select FirstName, LastName, tripName
from customer c
inner join reservation r
on c.CustomerNum = r.CustomerNum
inner join trip t
on r.TripID = t.TripID
where c.CustomerNum in (
select ir.CustomerNum
from reservation ir
group by ir.CustomerNum
having count(*) > 1
)
If you are using GROUP BY, all the fields you select must be in an aggregate function or included in the GROUP BY clause.
You must use having for filter an aggregated result (not where)
SELECT FirstName, LastName, tripName
FROM reservation
INNER JOIN customer on reservation.CustomerNum = customer.CustomerNum
INNER JOIN trip on reservation.TripID = trip.TripID
GROUP BY reservation.CustomerNum;
having COUNT(reservation.CustomerNum) > 1

MySQL GROUP BY and HAVING Clause

I am trying to write a script to show the names of every city with at least two customers, along with the number of customers in that city.
Here's what I have but I cannot figure out how to get the number of customers.
Am I close?
SELECT CONCAT (FName,' ',LName) AS Customers, city
FROM Customer
GROUP BY City
HAVING COUNT(CID) >= 2
Use count(*)
SELECT city , count(*)
FROM Customer
GROUP BY City HAVING COUNT(*) >= 2
As u can see from this example:
SELECT Employees.LastName, COUNT(Orders.OrderID) AS NumberOfOrders FROM (Orders
INNER JOIN Employees
ON Orders.EmployeeID=Employees.EmployeeID)
GROUP BY LastName
HAVING COUNT(Orders.OrderID) > 10;
you must enter COUNT (CID) in the select

Add results of two mysql queries

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;

select a column corresponding to max value in two joined tables

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

Returning distinct rows for multiple users

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.