Get SUM for same column but different relationships - mysql

I'm working on this database for a pet clinic (learning exercise), and what I want to do is to get the SUM for the same column, but different relationships.
These are my tables (only listing attributes used in query):
customer (customer_id, customer_name)
employee (employee_id, first_name, last_name)
pet (pet_id, owner_id, pet_name)
performed_service (performed_services_id, visit_id, service_id)
visit (visit_id, customer_id, employee_id, pet_id, date)
service (service_id, name, cost)
This is the query that I've tried, which so far gets all the data that I want, but not the SUMS correctly, which I cannot seem to understand how to do (if at all possible). What I'm trying to do is fetch the sum for service.cost for each pets visit, and sum of service.cost for all the visits that the customer has had, later I'm going to add a where clause on the date, so that it only shows instances of the current date:
SELECT
customer.customer_name,
pet.pet_name,
visit.date,
CONCAT(employee.first_name, ' ', employee.last_name) AS 'Veterenarian',
performed_service.service_id,
service.name AS 'Treatment',
service.cost AS 'Price',
SUM(service.cost) AS 'Pet Total',
SUM(service.cost) AS 'Customer Total'
FROM visit
INNER JOIN customer
ON visit.customer_id=customer.customer_id
INNER JOIN employee
ON visit.employee_id=employee.employee_id
INNER JOIN pet
ON visit.pet_id=pet.pet_id
INNER JOIN performed_service
ON visit.visit_id=performed_service.visit_id
INNER JOIN service
ON performed_service.service_id=service.service_id
GROUP BY performed_service.performed_service_id
Any help would be appreciated!

Related

Sql query to fetch multiple data from multiple tables

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.

Query: Find customers who have made purchase of every type of flower offered by shop

I need to Find customers who have made a purchase on every type of the flower bouquets offered by the shop. Output schema: (Cust)
Find distinct customers in the database who have not made any order during year 2017. You can compare date values by the standard operators <, >, <=, >=
Output schema: (Cust, CName)
Table Names:
Flowers (Prod, Name, Description, Price)
Customer (Cust, CName, CAddress, CCity, CZip, CState, Card, CardNo, Exp)
Order (Order, Prod, Cust, Date, RName, RAddress, RCity, RZip, RState)
What is the solution for these two queries?
For first query, You can try below -
SELECT C.CName
FROM Customer C
JOIN Order F ON C.CUST = O.CUST
JOIN Flowers F ON F.PROD = O.PROD
GROUP BY O.CUST
HAVING COUNT(DISTINCT PROD) = (SELECT COUNT(DISTINCT PROD) FROM Flowers)
For second query, You can try -
SELECT DISTINCT C.CUST, C.CName
FROM Customer C
WHERE C.CUST NOT EXIST (SELECT 1
FROM Order O
WHERE O.CUST = C.Cust
AND YEAR(Date) = 2017);

Determine total cost per user from 3 Different Tables

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.

MySQL query with multiple count statements in a effective way

Let's have 4 simple tables:
TABLE region (id, name)
TABLE country (id, name, region_id)
TABLE organization (id, name, country_id)
TABLE person (id, name, organization_id)
I want to make a query, where I would have:
Region name
Person count for region
Country name
Person count for country
Organization name
Person count for organization
Person name
For instance:
Europe, 20, Slovakia, 2, University of Life, 1, Somebody
How can I make those counts in a effective way in MySQL?
I have a huge query, where I have inline selects for each count, but this is not at all efficient. I was considering sum with case, but I don't quite grasp the concept if I have thousands of organizations with different names...
SELECT r.name as region, count(DISTINCT r.id) as region_total,
c.name as city, count(DISTINCT c.id) as country_total,
o.name as organization, count(DISTINCT o.id) as organization_total,
COUNT(p.id) as person_total
FROM region r
JOIN country c
on r.id= c.region_id
JOIN organization o
ON c.id = o.country_id
JOIN person p
ON o.id p.organization_id
GROUP BY r.id, c.id, o.id
ORDER BY r.id, c.id, o.id
I dont see how you want to include a person name here

MySQL query to count rows fulfilling two conditions and return an organised list of these counts

Our school's got a few extracurricular activities as popular as the one I am running and since it's got hundreds of members, but only a few mentors, we have a strict attendance policy that gets members kicked out after their third unexcused absence.
The PHP-JS-MySQL website I created for the purpose of running the activity stores people's attendance to meetings in this MySQL table:
meetings_attendance (meetings_id, members_id, attendance, excuse)
In this table, meetings_id and members_id are indices referring to the int primary keys in tables covering, obviously, meetings and members. attendance is an enum whose values can be "Pending","Present","Absent" or "Excused", and excuse is a varchar(300) which can be left null in case the member is present.
Since I'm running the program myself, I do not necessarily wish to include the kicking-out functionality in the website (I'd like to do it manually, contacting each member before they are kicked out and the status value in their row of the members table is set to "Inactive"). I'm trying to get a list of the members' names, email address and phone number, from the members table:
members (`id`, `firstname`, `lastname`, `email`, `phone`........)
I have been trying various combinations of MySQL queries to fetch a list of members' absence counts, to no avail. I've tried things like the following, and I have a feeling I should be using DISTINCT somewhere, but I can't pinpoint exactly where or how.
SELECT
firstname,
lastname,
email,
phone,
absences
FROM
meetings_attendance,
members
WHERE
absences = (
SELECT COUNT(*)
FROM meetings_attendance
WHERE attendance = "Absent"
)
AND members.id = meetings_attendance.members_id
Count the absences per member and keep those with a count >= 3 (using GROUP BY and HAVING). Then join the thus found members with the member table and show the results:
select
m.firstname,
m.lastname,
m.email,
m.phone,
a.absences
from members m
join
(
select members_id, count(*) as absences
from meetings_attendance
where attendance = "Absent"
group by members_id
having count(*) >= 3
) a on a.members_id = m.id;
SELECT firstname, lastname, email, phone, absences FROM members
WHERE id IN
(SELECT members_id FROM
(SELECT members_id, COUNT(*) FROM meetings_attendance
WHERE attendance = "Absent"
GROUP BY members_id
HAVING COUNT(*) >= 3 ) AS tab1)
try to format this code below and tell me whether it solve your problem
SELECT *,(SELECT COUNT(*) FROM table2 WHERE table2.field1 = table1.id) AS count FROM table1 WHERE table1.field1 = 'value'