I am having problem to figure out how to create a query for this scenario:
Here is updated version of my question.
I have 3 tables.
`customers`: `id` , `name` , `address`
`cars`: `id` , `license_nr` , `make` , `customer_id`
`services`: `id` , `car_id` , `description`
Every time a customer comes for a service a new record made in services table. I want to know counts of services for each customer. There is no direct relation between in services and customers.
EDIT: Correction of a column name in services table.
I think I will answer my own question. Maybe someone else will need this. Thank you all for your efforts.
SELECT customers.name, COUNT(*) AS visit_count
FROM services
JOIN cars ON cars.id = services.car_id
JOIN customers ON customer.id = cars.customer_id
GROUP BY customer_id
I get the result I want.
name | visit count
Amal Hopkins | 1
Dean Leach | 2
Here is the updated solution based on the updated question:
select count(s.id) as service_tickets, cust.id, cust.name, cust.address
from customers cust
left join cars c on c.customer_id = cust.id
left join services s on s.car_id = c.id
group by cust.id
I updated it so it would return 0 for customers who have no services on their cars.
SELECT customer, COUNT(*) FROM table GROUP BY customer;
UPDATE:
If visit means a row in services table, then we are OK because we simply need to count rows in services table. Foreign keys are not a problem. In fact, we can use join to see customer's name. So, the syntax should be:
SELECT s.CustomerID, c.Name, COUNT(*) FROM services s
join customer c on c.id=s.CustomerID
GROUP BY CustomerID, c.Name
Related
I want to get the customer who mostly borrowed films of category 3 in 2016, July
SELECT c_firstName, c_lastName, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID HAVING rental.c_ID=MAX((SELECT COUNT(rental.c_ID)
FROM customer, copies, rentalprocess, rental, film
WHERE customer.c_ID=rental.c_ID AND rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND film.f_ID=copies.f_ID AND
f_category=3 AND r_date LIKE "2016-07%" GROUP BY rental.c_ID))
But ir doesn't work because it said that the subquery returns more than one row
What can I do?
Max() is an aggregate function that needs to be in a select statement
SELECT
c_firstName
, c_lastName
, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID
HAVING rental.c_ID=
(
select
MAX(i.iID)
from
(
SELECT
COUNT(rental.c_ID) iID
FROM customer, copies, rentalprocess, rental, film
WHERE
customer.c_ID=rental.c_ID AND
rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND
film.f_ID=copies.f_ID AND
f_category=3
AND r_date LIKE "2016-07%"
GROUP BY rental.c_ID
) i
)
In this case the sub-select returns multiple rows but then you take the max value of that query
Comment from Mr Linoff is correct, you should use explicity joins:
SELECT
c_firstName
, c_lastName
, rental.c_ID
FROM customer, rental
GROUP BY rental.c_ID
HAVING rental.c_ID=
(
select
MAX(i.iID)
from
(
SELECT
COUNT(rental.c_ID) iID
FROM
customer
inner join rental
on customer.c_ID=rental.c_ID
inner join rentalprocess
on rentalprocess.r_ID=rental.r_ID
inner join copies
on rentalprocess.s_ID=copies.s_ID
inner join film on film.f_ID=copies.f_ID
WHERE
f_category=3
AND r_date LIKE "2016-07%"
GROUP BY rental.c_ID
) i
)
your code should look something like this, join the tables properly in the code.
I dont know wich columns and table would suit best for the solution becuse I dont got your full schema. but this should give faster query. Put more columns in the select if you wish.
select c_firstName | ' ' | c_lastName, count(rental.c_ID) as rentalCustomer
from customer
inner join rental
on join " connect the both tables"
innner join rentalprocess
on "connect rental with rentalprocess"
inner join copies
on " connect rentalprocess with copies"
inner join film
on "connect copies with film"
WHERE customer.c_ID=rental.c_ID AND
rentalprocess.r_ID=rental.r_ID AND
rentalprocess.s_ID=copies.s_ID AND
film.f_ID=copies.f_ID AND
f_category=3 AND r_date LIKE "2016-07%"
group by c_firstName, c_lastName, rental.c_ID
order by rental.c_ID desc;
I checked many posts with related questions, but couldnt find an answer.
I have 2 tables which have a one to many relationship. One is customers and the other one is projects. One customer can have many projects. their PK and FK are customer.customer_id and project_customer_id.
Now when I use the following SQL
SELECT *, COUNT(project.project_id) AS totalProjects
FROM `customer` LEFT JOIN `project`
ON `project`.`customer_id` = `customer`.`customer_id`
ORDER BY `customer`.`date_created` DESC
However when I get all my customers now it only returns the customers which actually have a project. I used inner, outer, left, union and right joins but no luck. I also tried DISTINCT but didnt work either.
Does anyone have any idea for such a query that it returns all customers even if they have no projects?
thanks in advance,
Rodney
Since you are only concerned with the count of projects "if I understood correctly from your question", either create a function to get you this count, or write a sub query like the example below...
SELECT
*,
(
SELECT COUNT(project.project_id) from project
WHERE
project.customer_id = customer.customer_id
) AS totalProjects
FROM
customer
ORDER BY customer.date_created DESC
Use this query:
SELECT *, COUNT(project.project_id) AS totalProjects FROM `customer` LEFT JOIN `project` ON `project`.`project_customer_id` = `customer`.`customer_id` GROUP BY `customer`.`customer_id` ORDER BY `customer`.`date_created` DESC
Not clear from your question, but I think you are trying to list all customers and if there are any projects associated with a customer then list the number of 'projects'? If that's your question then the below should solve it for you:
SELECT *, ISNULL((SELECT COUNT(*) FROM Project WHERE CustomerID = C.CustomerID),0) AS ProjectCount
FROM Customer C
ORDER BY C.Date_Created DESC
I'm sure this question makes no sense, sorry for that, best way I can explain it is visually.
My tables are:
category, comment, member and review.
I have a query which selects information from the 3 latest reviews
SELECT `reviewID` , `reviewTitle` , `reviewContent` , `reviewDate` , `gameRating` , `reviewImage` , `firstName` , `lastName` , `categoryName`
FROM member
INNER JOIN review
USING ( memberID )
INNER JOIN category
USING ( categoryID )
ORDER BY `reviewDate` DESC
LIMIT 3
result
Each review is assigned a reviewID, comments are also assigned a reviewID to determine which review the comment is for. I want to also count the amount of comments per review. Comments tables includes:
commentID reviewID memberID commentDate commentContent
I've tried
SELECT `reviewID`, `reviewTitle`, `reviewContent`, `reviewDate`, `gameRating`, `reviewImage`, `firstName`, `lastName`, `categoryName`, count(commentID) AS comments
FROM member INNER JOIN
review
USING (memberID) INNER JOIN
category
USING (categoryID) INNER JOIN
comment USING (reviewID)
ORDER BY `reviewDate` DESC
LIMIT 3
But it only gives this result
which is correct as that review has 2 comments, but the other 2 reviews have 0 comments so I assume it should just return null instead of not displaying the other reviews all together? Any help would be greatly appreciated.
You probably just need left joins:
SELECT member.*, count(commentID) AS comments
FROM member LEFT JOIN
review
USING (memberID) LEFT JOIN
category
USING (categoryID) LEFT JOIN
comment
USING (reviewID)
GROUP BY memberId
ORDER BY `reviewDate` DESC
LIMIT 3
You need a GROUP BY, but you should also remove all the non-member columns.
Let's say I have two tables Cities and Employees. Each employee associated with one city. How can I build a query resulting with all cities and will have additional column equals to number of employees associated with this city?
I tried the following:
SELECT *,COUNT(SELECT * FROM `Employees` WHERE `city_id` = `id`) AS `count` FROM `cities`
But it's not working.
Actually I have no idea where I should looking for. Hope that I will have any hint here.
You may try the following query using inner join between cities and employees table
SELECT cities.* ,COUNT( `Employees`.`id`) FROM `cities`
INNER JOIN `Employees` on `Employees`.`city_id` = `cities`.`id`
GROUP BY `cities`.`id`
If you prefer old style SQL you could try something like this
SELECT cityTable.`name`, employeesTable.employees_count
FROM (SELECT `id`, `name` FROM `Cities`)citiesTable,
(SELECT count(*) as employees_count, `city_id` FROM `Employees`)employeesTable
WHERE citiesTable.`id` = employeesTable.`city_id`
The predicate is: Give me all cities, and the number of employees belonging to them.
SELECT c.name, COUNT(e.id) cnt
FROM cities c
LEFT JOIN employees e
ON c.id = e.city_id
GROUP BY c.name
This will give you all cities with cnt zero if a city has no employees belonging to it
I got a MySQL Database where I store ship employees and their job experience. I got one table where I store the employees, one table where I store their previous jobs in the shipping department ( Type of Job , Years ) and another one table where I store their other previous jobs ( Type of Hob , Years ). All these are connected using the ID of the employee. When I fetch an employee I'd like to get the sum of his shipping and general experience, but the select query returns wrong sum for the general experience. I know this is cause by the multiple joins and because the tables are not joined properly, but I am not sure on how to fix this. Could you please help me?
P.S. I 'd like to do this with a single query.
Example of the query I use
SELECT id , name , SUM( s_exp.years ) , SUM ( g_exp.years )
FROM employees
LEFT JOIN s_exp ON employees.id = s_exp.id ,
LEFT JOIN g_exp ON employees.id = g_exp.id
GROUP BY employees.id
Maybe something like this:
SELECT id , name ,
(
SELECT
SUM(s_exp.years)
FROM
s_exp
WHERE
employees.id = s_exp.id
) AS s_total_years,
(
SELECT
SUM(g_exp.years)
FROM
g_exp
WHERE
employees.id = g_exp.id
) AS g_total_years,
FROM employees
Select id, sum(g_exp.years) GE, sum(s_exp.years) SE
From s_exp Natural Join g_exp
Where id = (Select id From employee Where name = ?)
group by id