I am working on a theatre booking system in MySql (My first SQL project). I have three tables:
Production (contains Title, BasicTicketPrice),
Performance (PerformanceDate, PerformanceTime, Title)
Booking (Email of person who booked, PerformanceDate, PerformanceTime, RowNumber).
Each person booked tickets for two or three performances (using their email to book).
I need to to write a query which will display the prices paid for all booked seats and I need to output the RowNumber, Email of person who booked and the Calculated Price.
I understand that I need to join these tables and make the query display a temporary column called Calculated Price but I don't know how to calculate the price.
I tried this:
SELECT DISTINCT b.RowNumber, b.Email, pr.BasicTicketPrice
FROM booking b, production pr performance p
WHERE p.Title=b.PerfDate*b.PerfTime*b.RowNumber;
SELECT CONCAT (PerfDate, PerfTime, RowNumber) AS BookingID FROM booking;
SELECT RowNumber, Email, CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID FROM booking;
SELECT RowNumber, Email, CONCAT((CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID
FROM booking)BasicTicketPrice*BookingID);
SELECT RowNumber, Email, CONCAT(PerfDate, PerfTime, RowNumber) AS BookingID INTEGER
FROM booking;
SELECT RowNumber FROM booking
LEFT JOIN (SELECT Title FROM performance WHERE '2017-11-01 19:00:00' Email IS NULL);
But it didn't work.
Any suggestions? I will be grateful for any ideas.
Assuming:
One row in Bookings per booked seat
Title to be a suitable primary key for Production
PerformanceDate, PerformanceTime to be a suitable primary composite key for Performance
You'll be looking to join the three tables together as per the keys assumed above. It seems you wish to group the bookings together per performance, by the person booking the tickets - if so, you'll need to use an aggregate to show the seat numbers (I've used GROUP_CONCAT to delimit them), as well as to COUNT the tickets purchased and multiply by the ticket cost.
SELECT
b.Email, prod.Title, per.PerformanceDate, per.PerformanceTime,
GROUP_CONCAT(RowNumber) AS BookedSeats,
COUNT(RowNumber) * prod.BasicTicketPrice AS TotalCost
FROM Booking b
INNER JOIN Performance per
ON b.PerformanceDate = per.PerformanceDate
AND b.PerformanceTime = per.PerformanceTime
INNER JOIN Production prod
ON per.Title = prod.Title
GROUP BY
b.Email, prod.Title, per.PerformanceDate, per.PerformanceTime, prod.BasicTicketPrice
ORDER BY prod.Title, per.PerformanceDate, per.PerformanceTime;
Technically, we should include all non-aggregated columns in the GROUP BY, hence prod.BasicTicketPrice is listed as well.
Related
Given the following tables:
• Clients (ClientId, Name, Surname, Age)
• Products (ProductId, Name, Price)
• Purchases (Purchaseld, Date, ClientId, Productid)
I need to write an SQL query that shows the quantity of purchases made by clients. It must only show the clients who made more than 1 purchase. The result should contain the following fields: Full name (i.e. "john rambo"), Quantity of purchases.
I have written this query but results are not coming correct
SELECT Concat(clients.name, clients.surname)
FROM clients
JOIN products
ON clients.name = products.name
JOIN purchases
ON products.productid = purchases.productid
GROUP BY clientid
HAVING Count(clientid) > 1
SELECT Concat(clients.name, ' ', clients.surname),
count(*) as number_of_orders
FROM clients
JOIN purchases
ON products.productid = purchases.productid
GROUP BY Concat(clients.name, ' ', clients.surname)
HAVING Count(clientid) > 1
As noted in the comments, your join to products doesn't make much sense - your asking to only return records where there's a product that matches a client's first name.
CONCAT will glue the two fields together (e.g. "JohnRambo")
It must only show the clients who made more than 1 purchase.
Your question has no mention of products, so there is no need for that in the query:
SELECT CONCAT(c.name, c.surname)
FROM clients c JOIN
purchases p
ON p.ClientId = c.ClientId
GROUP BY c.ClientId, CONCAT(c.name, c.surname)
HAVING COUNT(*) > 1 ;
Note that the ClientId presumably uniquely defines the clients -- not the names. So the ClientId should be part of the aggregation.
Hey I've been killing myself trying to figure out how to do these queries. Can someone help me out.
These are the tables I have currently.
BOOKING
HOTEL_NO
GUEST_NO
DATE_FROM
DATE_TO
ROOM_NO
GUEST
GUEST_NO
GUEST_NAME
CITY
ADDRESS
ZIP_CODE
HOTEL
HOTEL_NO
HOTEL_NAME
CITY
ADDRESS
ZIP_CODE
STAR
ROOM
ROOM_NO
HOTEL_NO
ROOM_TYPE
PRICE
And these are the queries I need to do.
-List the guests that have all their bookings (past and present) in the same hotel.
-Create a view VIP-Guest that lists guests who have reservations for only 4 star hotels or
4 star hotels
-Among the VIPs find the guest with the largest total stay (in term of number of days).
Express this as a query with the view and without the view
Can someone help me out?
this should get you started. to post on stackoverflow, you need to come with specific questions or errors or problems. like for the query you posted in the comments up top.... that could be a question in itself: "I have these tables, this one specific goal (question/result set), and I tried this query... it gives me this result or it gives me this error."
BOOKING: HOTEL_NO, GUEST_NO, DATE_FROM, DATE_TO, ROOM_NO
GUEST: GUEST_NO, GUEST_NAME, CITY, ADDRESS, ZIP_CODE
HOTEL: HOTEL_NO, HOTEL_NAME, CITY, ADDRESS, ZIP_CODE, STAR
ROOM: ROOM_NO, HOTEL_NO, ROOM_TYPE, PRICE
all guests and bookings...
-- all guests: select * from guest;
-- all bookings: select * from booking;
select *
from guest
join booking on guest.guest_no = booking.guest_no;
-- which is the same as...
select *
from guest, booking
where guest.guest_no = booking.guest_no;
-- and... your comments query was missing a group by clause
select guest_no, guest_name, count(*) as booking_count
from guest
join booking on guest.guest_no = booking.guest_no
group by guest_no, guest_name;
select guest_no, guest_name, count(distinct hotel_no) as hotel_count
from guest
join booking on guest.guest_no = booking.guest_no
group by guest_no, guest_name
having count(distinct hotel_no) = 1;
and I count(distinct hotel_no) because... they might have 3 bookings at Hotel A and 1 at Hotel B. The basic join would give me 4 rows for that person. I don't care how many bookings. I care how many hotels. So I want to count the distinct occurrences of hotel_no per person (there's that group by) instead of every row.
guests by their stars...
-- so we have to get guest and hotel joined. bc hotel has stars.
-- booking has hotel_no. so... we can use that last query and
-- join in HOTEL to get the star information. in the WHERE you
-- will want to put your filter for the number of stars that you
-- are looking for =4 or >=4 or something like that.
-- you might want to check out DISTINCT to get just a list of names
-- instead of a row for each booking.
number of days they stayed...
-- use the second query.
-- datediff(date_to, date_from) as days_stay gives you the length of stay
-- i don't know what the view is.
-- to get the top length could go two ways... either ORDER BY and LIMIT if there is
-- only one person with the top length (let's say 10 days). if there are many people
-- who have stayed 10 days, you'll need to do a MAX on the days_stay and either join
-- that in or use it in the WHERE as a nested select.
this assumes there is a single highest length of stay. only one person stayed 10 days.
SELECT guest_no, guest_name, datediff(date_to, date_from) days_stayed
FROM vip_guest
join booking on vip_guest.guest_no = booking.guest_no
order by datediff(date_to, date_from) desc
limit 1,1
this should work for many... (i'm not testing these... just kind of looking at it)
SELECT distinct guest_no, guest_name, datediff(date_to, date_from) max_stay
FROM vip_guest
join booking on vip_guest.guest_no = booking.guest_no
where datediff(date_to, date_from) = (
select max(datediff(date_to, date_from)) as days_stayed
from booking )
the nested query gets the maximum stay length of everyone. vip_guest and bookings joined together give us guest and date imfo. we will get all bookings for every vip_guest. so we want to filter it down to where stay lengths == the max stay length. in case a person had multiple 10 day stays (my arbitrary max stay length)... use distinct.
now... thats a good point about the nested query. i don't know what is in your view. it is possible none of the max vip guests had a stay as long as the max stay length. in that case, this query would return nothing.
I have three tables:
Table1: Salary
Fields: ID,Account_Num,Amount
Table2: Other_Income
Fields: ID,Account_Num,Amount
Table3: Expenses
Fields: ID,Account_Num,Amount
From the above tables,how to write a query which return a result, list all account from these table, and shows the balance of every account in these tables.
Result should show Account_num,Salary,Other_Income,Expenses,
balance(balance=Salary.amount+Other_Income.amount-expenses.amount)
These three table may contains some different account number.
I have been thinking of this so long, tried union and join but still cant make it.
Somebody show/guide me?
I've had some luck with the following query. Essentially, I combine all the transactions in the Salary, Other_Income and Expenses tables into a single temp table named combined, and then use group by to sum all the transactions!
select Account_Num, sum(Amount)
from (
select Account_Num, Amount from Salary union
select Account_Num, Amount from Other_Income union
select Account_Num, -Amount from Expenses
) as Combined
group by Account_Num;
Following query might help , provided that every account has salary against it.
select Account_Num,(total-d.Amount) as final_amount ( select Account_Num, ifnull(a.Amount,0)+ifnull(b.Amount,0) as total from Salary a
left join Other_Income b on a.Account_Num=b.Account_Num ) c
join Expenses d on c.Account_Num=d.Account_Num
SELECT Sal.`Account_Num`, sal.`Amount` AS Salary, ot_in.`Amount` AS ExtraIncome , exp.`Amount` AS expenses, (sal.`Amount`+ot_in.`Amount`-exp.`Amount`) As Balance FROM Salary AS Sal INNER JOIN Other_income AS ot_in ON Sal.`Account_Num` = ot_in.`Acount_num` INNER JOIN Expenses AS exp ON Sal.`Account_Num` = ex.`Account_Num`
Here joining three of the table on a condition where you get the common account number from all three and extracting the correponding amounts from each , calculating the rest balance with a formulae given subtracting expenses from income.. i hop this will help.
I have this tables:
Sales(Product Code,No Customer, amount, Id sale)
Customer ( No Customer, Name, Adress, Phone, town)
Products (Product Code, Description, Price)
Well, my question is, how do I do this query in MySQL? :
Name of the customers who purchased all the products.
I have only this query that joins me the two tables that I have to use:
Select Name from Customer join Sales using(No Customer);
But I have the question, how do I separate the Customers that have all the products purchased?
Thanks for the help.
This is called relational division.It gets the result using contradiction.This is called classical method.
select c.name from customer c where not exists
(select * from products p where not exists
(select * from sales s where p.productcode=s.productcode and c.nocustomer=s.nocustomer))
There is one more way to do these type of queries.It was invented a few years back and published in a research paper which claimed that the new way was much more faster than the classical way.I will quote the source soon.The new method is using group by and count(*) like this:
select c.customername from customer c,sales s,product p
where p.productcode=s.productcode and c.nocustomer=s.nocustomer
group by s.nocustomer having count(*)=
(select count(distinct p1.productcode) from product p1)
The above query just compares the count of products bought by customer with the total count of distinct products in the products table and returns the name of the customers who matches the criteria.On a personal note I like the classical method more than this but the new method has a much more fast response then the classical method and I have checked it myself.Hope it helps.
Pretty new to sql statements here so this one is a bit tricky for me.
I have two tables: sold and product. Sold(SID, UPC, Date) Product(UPC, Name, Brand)
I need to find in how many stores(sid) does one brand outsell another brand.
I was thinking it was something like:
select count(*) from sold natural join product
where count(brand = 'sony') > count(brand = 'samsung');
Clearly that isn't valid however...
SELECT COUNT(*)
FROM (
SELECT SID
FROM Sold
JOIN product
ON product.UPC = Sold.UPC -- otherwise we have a cartesian product
GROUP BY SID -- if we need totals _by store_, we need to group on that.
HAVING SUM(brand='sony') > SUM(brand='samsung')
) Totals.