Reputation: 843
I have been trying to do the following exercise, which is to create a query using SQL, "Find number of salesmen who have more than 3 clients in a week. Display the staff ID, staff name, client ID, client name and number of clients who the salesman met with."
The entities and relevant fields are:
Staff: [Staff_ID (PK), Staff_Name, ...]
Clients: [Client_ID (PK), Client_Name, Staff_ID (FK), ...]
Sales: [Sale_ID (PK), Client_ID (FK), Staff_ID (FK), Date_of_Sale, ...]
(All data are strings except Date_of_Sale, which is in DATE format)
I've tried to accomplish this, with the following:
SELECT t.Staff_ID, t.Staff_Name, COUNT(s.Client_ID),
COUNT(c.Client_Name), DATEPART(wk, s.Date_of_Sale) as Week
FROM Clients c, Staff t, Sales s
GROUP BY DATEPART(wk, s.Date_of_Sale), t.Staff_ID, t.Staff_Name
HAVING COUNT(DATEPART(wk, s.Date_of_Sale)) > 3
I know it's incorrect, but I don't know how to fix it, as I am very unskilled in sql. I want to understand how to do this and I could (to a limited extent) by reverse engineering it. Even better, if someone were to explain it for me, I would much appreciate it, thanks in advance.
Upvotes: 0
Views: 88
Reputation: 3042
There's a big difference between number of clients who the salesman met with and the number of sales the salesman made. Mainly, whether or not to count repeat visits to the same client. The former says no, the latter says yes, because the number of clients hasn't changed but the number of sales has.
-- Get list of clients with sales greater than 3 in a week
WITH SalesCount AS (
SELECT Client_ID AS 'Client', DATEPART(wk, Date_of_Sale) AS 'week',
COUNT(Staff_ID) AS 'Sales_Count'
FROM Sales
GROUP BY DATEPART(wk, Date_of_Sale), Client_ID
HAVING COUNT(Staff_ID) > 3 ),
-- Shorten the list to unique entries and add the StaffID
ClientList AS (
SELECT DISTINCT sc.Client, c.Staff_ID
FROM SalesCount AS sc
INNER JOIN Clients AS c ON sc.Client = c.Client_ID) ,
-- Create a count of clients visited
ClientCount AS (
SELECT COUNT(l.Client) AS visitors, l.Staff_ID
FROM ClientList AS l
GROUP BY l.Staff_ID)
SELECT cc.visitors, cc.Staff_ID, l.Client, t.Staff_Name
FROM ClientCount AS cc
INNER JOIN ClientList AS l ON cc.Staff_ID = l.Staff_ID
INNER JOIN Staff AS t ON t.Staff_ID = l.Staff_ID
INNER JOIN Clients AS c ON l.Client = c.Client_ID
Upvotes: 1
Reputation: 928
Here we go
WITH CTE AS (
SELECT *, DATEPART(wk, s.Date_of_Sale) as SALES_WEEK
FROM Clients c
INNER JOIN Sales s ON c.Client_ID = s.CLIENT_ID
INNER JOIN Staff t ON t.STAFF_ID = s.STAFF_ID
)
SELECT SALES_WEEK, Staff_ID, Staff_Name, COUNT(1) AS NO_OF_SALES
FROM CTE
GROUP BY SALES_WEEK, Staff_ID, Staff_Name
HAVING COUNT(1) > 3
Hope this works as expected
Upvotes: 1