Display Count of sales for employees - mysql

I have three tables. PersonalDetail, Employee and Orders. Personal details has data about names and stuff. Employee table has professional data. Orders have sales history.
Table PersonalDetail
personalID FirstName LastName
1 test test
2 test test
3 test test
4 test test
5 test test
Table Employee:
EmployeeID personalID hireDate Status
001 1 test test
002 2 test test
003 3 test test
004 4 test test
005 5 test test
and more data
Table Orders:
OrderID customerID EmployeeID ShipmentStatus
1 10 002 P
2 182 001 P
3 22 005 P
4 10 002 P
5 89 003 P
6 76 004 P
7 99 001 P
8 111 001 P
9 123 002 P
10 647 001 P
I want to get the end result as:
employeeID FirstName,LastName Count(sales to customers)
001 test test 4
002 test test 3
003 test test 1
004 test test 1
005 test test 1
So far, I have this:
SELECT e.employeeID, Concat (p.firstName,' ', p.lastName) AS Name, o.customerID
FROM Employee ((
INNER JOIN PersonalDetail ON e.personalID = p.personalID)
INNER JOIN Orders ON e.employeeID = o.employeeID)
ORDER BY employeeID;
This gives me the following result:
employeeID Name CustomerID
001 test test 182
001 test test 99
001 test test 111
001 test test 647
002 test test 10
002 test test 10
002 test test 123
003 test test 89
004 test test 76
005 test test 22
I know how to display employee name against each customer order but struggling with displaying the count of orders for a particular employee.

You can join and aggregate:
select
e.EmployeeID,
concat(e.FirstName, ',', e.LastName) employeeName,
count(*) no_sales
from employees e
inner join sales s on s.EmployeeID = e.EmployeeID
group by e.EmployeeID, e.FirstName, e.LastName
order by no_sales desc

To avoid error on 'order by' use the count itself:
select
E.EmployeeID,
concat(E.FirstName, ',', E.LastName) employeeName,
count(S.*) no_sales
from employees E
inner join sales S on S.EmployeeID = E.EmployeeID
group by E.EmployeeID, E.FirstName, E.LastName
order by count(S.*) desc

Related

add date to every name

hello please help me to solve this,, i am using mysql.. and I think, needing a full outer join to solve it,.
this is my query:
SELECT
e.NIK,
e.name,
a.dt
FROM
employee e
LEFT JOIN
attandence a
ON e.NIK=a.NIK
WHERE
month(a.dt)=12 AND year(a.dt)=2021
GROUP BY
e.NIK
this is the result:
NIK
name
dt
001
ana
23/12/2021
001
ana
24/12/2021
001
ana
26/12/2021
001
ana
27/12/2021
002
susi
23/12/2021
002
susi
24/12/2021
002
susi
25/12/2021
002
susi
26/12/2021
but i need to join it one more time with this table :
holidayTable
id
mark
dt
1
off_day
22/12/2021
2
chrismast
25/12/2021
I've tried using left/right/cross join, but it doesn't work
The result I want is like this:
NIK
name
dtWork
holiday
001
ana
null
22/12/2021
001
ana
23/12/2021
null
001
ana
24/12/2021
null
001
ana
null
25/12/2021
001
ana
26/12/2021
null
001
ana
27/12/2021
null
002
susi
null
22/12/2021
002
susi
23/12/2021
null
002
susi
24/12/2021
null
002
susi
25/12/2021
25/12/2021
002
susi
26/12/2021
null
You need a calendar table to achieve the output.
As of now I used union between holidaytable and attendance as Calendar.
You can achieve your desired result with below query.
SELECT e.nik,
e.name,
a.dt AS dtWork,
h.dt AS holiday
FROM employee e
CROSS JOIN(SELECT dt
FROM holidaytable
UNION
SELECT dt
FROM attendance)cal
LEFT JOIN attendance a
ON e.nik = a.nik
AND a.dt = cal.dt
LEFT JOIN holidaytable h
ON h.dt = cal.dt
WHERE a.dt IS NOT NULL
OR h.dt IS NOT NULL
ORDER BY nik ASC,
cal.dt ASC
SQLFiddle: Try it here
A union where the first part gets attendence and the second gets holidays (with as you thought a cross join) including a dummy column to assist ordering
select e.id,employeelastname,a.dt attendence,null holiday,a.dt as orderdt
from employees e
left join attendence a on a.nik = e.id
union
select e.id,employeelastname,null,h.dt holiday,h.dt
from employees e
cross join holidays h
order by id,orderdt;

How to join based on max timestamp in SQL?

So I have a df like this:
ID fruit
001 grapes
002 apples
002 mangos
003 bananas
004 oranges
004 grapes
And I want to join the following onto it:
ID store_time
001 2021-04-02 03:02:00.321
002 2021-04-02 02:02:00.319
002 2021-04-03 12:02:00.319
002 2021-04-04 13:02:00.312
003 2021-04-02 19:02:00.313
004 2021-04-02 15:02:00.122
004 2021-04-01 11:02:00.121
So all I want to do is join based on just the most recent timestamp. So leave the others behind and have only the number of rows as there are in the fruit df.
Final output:
ID fruit timestamp
001 grapes 2021-04-02 03:02:00.321
002 apples 2021-04-04 13:02:00.312
002 mangos 2021-04-04 13:02:00.312
003 bananas 2021-04-02 19:02:00.313
004 oranges 2021-04-02 15:02:00.122
004 grapes 2021-04-02 15:02:00.122
Aggregate in the 2nd table to get the most recent store_time for each ID and then join to the 1st table:
SELECT t1.ID, t1.fruit, t2.timestamp
FROM table1 t1
LEFT JOIN (
SELECT ID, MAX(store_time) timestamp
FROM table2
GROUP BY ID
) t2 ON t2.ID = t1.ID
I used a LEFT join just in case table2 does not contain all the IDs of table1.
If this is not the case then you can change it to an INNER join.
you need a subquery for max tme stamp
select a.id, a.fruit, b.max_time
from my_table_fruit a
inner join (
select id, max(store_time) max_time
from my_table_time
) b on b.id = a.id

MySQL JOIN Queries to find references and conversions

I have the following three tables User, References and Conversions. The goal is to find out which users have given how many references and how many of these references have been converted.
user
id user_id
1 001
2 002
3 003
4 004
5 005
6 006
7 007
8 008
9 009
10 010
references
id referer_id referee_id
1 001 005
2 001 006
3 002 007
4 003 008
5 004 009
6 005 010
conversions
id user_id
1 005
2 006
3 007
4 008
5 009
REPORT
id references(count) conversions(count)
001 2 2
002 1 1
003 1 1
004 1 1
005 1 0
Please suggest a MYSQL Query to produce the above Report.
Copied from the comment into original question
SELECT
user_id,
referenceCount,
conversionCount
FROM
users u
JOIN (SELECT referer_id,
COUNT(referee_id) AS referenceCount
FROM references
GROUP BY referer_id) r
ON r.referer_id = user_id
LEFT JOIN (SELECT user_id, COUNT(user_id) AS conversionCount
FROM conversions) c
ON c.user_id = r.referee_id GROUP BY u.user_id
You are on the right track with joins, but they should be left-joins.
SELECT
u.user_id,
count( distinct r.referer_id ) as CntRefs,
count( distinct c.user_id ) as CntConvert
FROM
users u
LEFT JOIN references r
on u.user_id = r.referer_id
LEFT JOIN conversions c
on r.referee_id = c.user_id
group by
u.user_id
I was able to achieve my result using the following SQL command. Many thanks to #DRapp for the help.
SELECT
u.user_id,
count( r.referer_id ) as CntRefs,
count( c.user_id ) as CntConvert
FROM
users u
JOIN reference r
on u.user_id = r.referer_id
LEFT JOIN conversions c
on r.referee_id = c.user_id
group by
u.user_id

Datediff in date format

I have 2 tables with structure as
Emp Table
id name
001 Smith
002 Jerry
Leave
sr.no reason from_date to_date request_by status
1 PL 2011-12-11 2011-12-15 001 Declined
2 PL 2011-11-13 2011-11-13 001 Approved
3 PL 2011-10-02 2011-10-05 002 Declined
Now I have written this query
select DATEDIFF(Leave.from_date,Leave.to_date)as cdate,
Emp.id as emp
from Leave left join Emp
on Leave.request_by=Emp.id
gives me difference between these 2 dates like...
cdate emp
-4 001
0 001
-3 002
The first thing about this output difference between '2011-12-11 & 2011-12-15 ' need to be 5 as for 5 consecutive days employee is absent. That we achieve it.
But I need this cdate in date format like('%Y%m%d') and + if date difference is say -4 then 4 records should be displayed for that.
So I want to write a query which gives output like this......
cdate emp
2011-12-11 001
2011-12-12 001
2011-12-13 001
2011-12-14 001
2011-12-15 001
2011-11-13 001
2011-10-02 002
2011-10-03 002
2011-10-04 002
2011-10-05 002
So can anybody tell me what how should I need to write my query to get this output?
Try this query -
CREATE TABLE temp_days(d INT(11));
INSERT INTO temp_days VALUES
(0),(1),(2),(3),(4),(5),
(6),(7),(8),(9),(10),
(11),(12),(13),(14),(15); -- maximum day difference, add more days here
SELECT l.from_date + INTERVAL td.d DAY cdate, e.id emp
FROM
`leave` l
LEFT JOIN Emp e
ON l.request_by = e.id
JOIN temp_days td
ON DATEDIFF(l.to_date, l.from_date) >= td.d
ORDER BY
e.id

I need help writing a summation query in MySQL

I have a table that looks like this:
posid sales eid
1 20 001
1 20 002
1 30 001
2 30 001
1 30 002
2 30 001
1 30 002
2 20 002
2 10 002
I want to write a query that would give me sum of sales for each employee on particular pos. the result needs to be like this.
pos id emp id sales
1 001 50
1 002 80
2 001 60
2 002 30
How would I do this?
Use group by:
select t.posid
, t.eid
, sum(t.sales) as sales_by_posid
from mytable t
group by t.posid, t.eid
order by sales_by_posid desc
SELECT
posID, empID, sum(sales)
FROM your_table
GROUP BY posID, empID
ORDER BY posID, empID
Here's a group by tutorial: http://www.tizag.com/mysqlTutorial/mysqlgroupby.php