I need some advice with a Select: I need to sum an amount by employee and month. With a Group by I am able to select the Month - the amount will be summed - but not by employee but by month:
SELECT MONTHNAME(datum) AS Monat,ID AS id, STATUS AS STATUS, MA AS Mitarbeiter,SUM(preis) AS Preis
FROM wccrm_prov
GROUP BY MONTHNAME(datum)
The answer could be similar to
SELECT
MONTHNAME(datum) AS Monat
, EMPLOYEE
,ID AS id
,STATUS AS STATUS
,MA AS Mitarbeiter
,SUM(preis) AS Preis
FROM wccrm_prov
GROUP BY MONTHNAME(datum), EMPLOYEE
I used a new field EMPLOYEE, as I'm not familiar with your non-english language used in the question query text. You can obviously swap this with your Employee field
Related
I need to compute employees' monthly salaries based on meetings attended, deductions and bonuses given;
Employees have different pay per meeting based on their job position.
The solution is:
salary = (Pay_per_minute * meetings_attended) + bonuses - deductions ;
I have four tables:
Jobs: Id, title, pay_per_meeting
Employees: Id, Name, job_id
Bonuses: Id, amount, employee_id, date
Deductions: Id, amount, employee_id, date
Meetings: Id, employee_id, date
SELECT
COUNT(meetings.employee_id) as meetings_attended,
COUNT(deductions.amount) as debt,
COUNT(bonuses.amount) bonus,
(SELECT jobs.pay_per_attendance from jobs where jobs.id = (select job_id from employees where id=meetings.employee_id)) as pay,
((meetings_attended * pay) + bonus - debt) as salary
FROM meetings
JOIN deductions ON deductions.employee_id = meetings.employee_id
JOIN bonuses ON bonuses.employee_id = meetings.employee_id
WHERE meetings.employee_id = 1
GROUP BY MONTH(meetings.date), MONTH(deductions.date), MONTH(bonuses.date)
The above query returns many incorrect values whenever i remove the salary line but gives error of unknown column pay, meetings_attended, debt and bonus, am sure something is wrong with the grouping but i can't just see it.
You can't refer to column aliases in the same select list as they're defined, you need to refer to the underlying column. And a subquery can't access an aggregate calculated in the main query. You need to repeat the aggregate expression, or move everything into a subquery and do the calculation with it in an outer query.
Also, all your COUNT() expressions are going to return the same thing, since they're just counting rows (I assume none of the values can be NULL). You probably want COUNT(DISTINCT <column>) to get different counts, and you need to use a column that's unique, so they should be the primary key column, e.g. COUNT(DISTINCT deductions.id).
Another problem is that when you try to sum and count values when you have multiple joins, you end up with a result that's too high, because rows get duplicated in the cross product of all the tables. See Join tables with SUM issue in MYSQL. The solution is to calculate the sums from each table in subqueries.
SELECT m.month, m.meetings_attended, d.debt, b.bonus,
m.meetings_attended * j.pay_per_meeting + b.amount - d.amount AS salary
FROM (
SELECT MONTH(date) AS month, COUNT(*) AS meetings_attended
FROM meetings
WHERE employee_id = 1
GROUP BY month) AS m
JOIN (
SELECT MONTH(date) AS month, COUNT(*) AS bonus, SUM(amount) AS amount
FROM bonuses
WHERE employee_id = 1
GROUP BY month) AS b ON m.month = b.month
JOIN (
SELECT MONTH(date) AS month, COUNT(*) AS debt, SUM(amount) AS amount
FROM deductions
WHERE employee_id = 1
GROUP BY month) AS d ON m.month = d.month
CROSS JOIN employees AS e
JOIN jobs AS j ON j.id = e.job_id
WHERE e.employee_id = 1
I have a table with orders in which in Comments record there is a name of the order creator.
There is 3 sales people. I want to fetch statistics from each sales person.
I came up with below query to output one person's orders and it works fine but I really struggle if it possible in one select query to fetch orders of each sales person and output in the same table. I tried Union and select within select but I guess I am constructing the query wrong. The below works fine to output just Adam's orders(Qty sold and total Sales value for that person).Thanks for any tips.
SELECT MONTHNAME(orders.despatched) as Month, YEAR(orders.despatched) as Year,
SUM(orders.price) as AdamSales, COUNT(orders.comment) as AdamQt FROM orders
WHERE
orders.comment LIKE '%Adam%' AND
orders.status = 'despatched' AND
orders.despatched BETWEEN '$d1' AND '$d2'
GROUP BY YEAR(orders.despatched), MONTH(orders.despatched)
order by orders.despatched ";
I know that possibly grouping by Person would be best if only the person's name wasn't just a string somewhere inside Comment record.
you can do group by on the case statement based on the comments
SELECT
( case when ORDERs.comments LIKE '%Adam%' THEN 'Adam'
when ORDERS.comments LIKE '%Peter%' THEN 'Peter' END ) as 'Person'
MONTHNAME(orders.despatched) as Month,
YEAR(orders.despatched) as Year,
SUM(orders.price) as Sales,
COUNT(orders.comment) as Qt FROM orders
WHERE
(orders.comment LIKE '%Adam%' OR orders.comment LIKE '%Peter%' ) AND
orders.status = 'despatched' AND
orders.despatched BETWEEN '$d1' AND '$d2'
GROUP BY YEAR(orders.despatched), MONTH(orders.despatched),
( case when ORDERs.comments LIKE '%Adam%' THEN 'Adam'
when ORDERS.comments LIKE '%Peter%' THEN 'Peter' END )
order by orders.despatched
If the person's name is just a string, then what you need is to Group By on a Case expression that will return 1 for the first person, 2 for the second, etc.; something like:
Group by Case When orders.comment LIKE '%Adam%' then 1 When ... End, ...
Or course, the real solution would be to add a table for Persons and add a relationship to it.
All recorders in sales & purchase table are only entered Once. I have checked it carefully. However I wish to combine these two tables in such a way that both tables will be completely fetched. here is my query
note that timestamp column has mysql DATE format
Select
sales.ID as sid,
sales.saleHatsh,
sales.timestamp as sdate,
sales.gatePass as sGP,
sales.pname as sPN,
sales.description as sDES,
sales.balance as sbal,
purchase.ID as pid,
purchase.purchaseHatsh,
purchase.timestamp as pdate,
purchase.gatePass as pGP,
purchase.pname as pPN,
purchase.description as pDES,
purchase.balance as pbal
from sales,purchase
where sales.timestamp='2013-11-11' OR purchase.timestamp='2013-11-11'
here is the result of my query & sales & purchase table
Sales table only have 2 recorder
Purchase table only has 4 recorder
What is happening there is that you are not joining those tables in any way. so you are getting all the possible matches from those tables. Looking at the columns i don't think you want to JOIN, but probably you want a UNION instead:
SELECT
sales.ID AS id,
sales.saleHatsh AS hatsch,
sales.TIMESTAMP AS date,
sales.gatePass AS GatePass,
sales.pname AS pname,
sales.description AS Description,
sales.balance AS balance,
'SALE' AS transanctionType
FROM sales
WHERE sales.TIMESTAMP = '2013-11-11'
UNION
SELECT
purchase.ID,
purchase.purchaseHatsh,
purchase.TIMESTAMP,
purchase.gatePass,
purchase.pname,
purchase.description,
purchase.balance,
'PURCHASE'
FROM purchase
WHERE purchase.TIMESTAMP = '2013-11-11'
I added a column "transactionType" for you to identify which ones are sales or purchases.
Trying to create a notification mail to my clients that have invoices due.
Here is my table
Name Amount Duedate
Joe#blah 10.00 2011-04-13
Joe#blah 15.00 2011-04-13
Jill#ugg 20.00 2011-05-20
Jim#yuck 25.00 2011-04-13
Joe#blah 15.00 2011-05-20
Because Joe is in there twice, how do I supress the second joe, so I don't notify him twice. I'd like it to return only:
Joe#blah
Jim#yuck
How do i do this in mysql?
Thanks
SELECT DISTINCTROW Name FROM Table WHERE DueDate (<=> meets your criteria of when it's "due")
Since you're only selecting on Name the DISTINCTROW will only return one instance of each Name.
SELECT DISTINCT Name FROM your_table WHERE Duedate < NOW()
SELECT syntax look at DISTINCT section
This query should give you unique names with due date falls in past or today.
Select
B.*
From
Invoicetable A,
(SELECT DISTINCT Name FROM Invoicetable WHERE Duedate <= NOW) B
where
A.Name = B.Name
I've got two tables in MySql
1 (Staff): Id/Name/SecondName
2 (fee):
Id/StaffId/Date(yyyy-mm-dd)/HoursWorked(hh:mm)/fee(int)/workType
There is also a script adding records to fee table.
I'm trying to group data in php to create html table like:
Name, Second Name | January 2009 | 123:45 hours | 2100,00 USD
February 2009...
March 2009 ....
Next person... etc.
So generally I'm trying to sum fee and hours in specific month and print a report from database...
And I need some advice/help... What is the bast way to create table like this?
Maybe something like this? Not tested though...
SELECT s.Name, s.SecondName, CONCAT(DAYOFMONTH(f.Date),', ',YEAR(f.Date)),
SUM (f.HoursWorked), SUM(f.Fee)
FROM Staff s
JOIN Fee f ON f.StaffId = s.Id
GROUP BY s.Id, YEAR(f.Date), MONTH(f.Date)
Edit: Ofcourse you need to group on s.Id...
That's not the best way, but if you want to do it with one query (it's easy to export to Excel):
SELECT
s.Name,
s.SecondName,
DATE_FORMAT('%M %y', f.`Date`),
SEC_TO_TIME( SUM( TIME_TO_SEC( `HoursWorked` ) ) ) as TotalHours,
sum(fee) AS TotalFee
FROM
Staff AS s
INNER JOIN fee AS f on s.id = f.StaffId
WHERE
1
GROUP BY s.id, YEAR(f.`Date`), MONTH(f.`Date`)
You cal also query stuff:
// that's not a real function, just get all Staff into $staff
$staff = QueryRows(SELECT * FROM Staff);
and then query fee:
foreach($staff as $s){
// use this query to query statistics
SELECT * FROM fee
WHERE StaffId = $s['id']
GROUP BY StaffId, YEAR(f.`Date`), MONTH(f.`Date`)
}
I'm not 100% sure about this being perfect but it should definitely point you in the right direction. The AVG() function calls might be unnecessary.
SELECT
Name,
SecondName,
SUM(fee.HoursWorked) as HoursWorked,
SUM(fee.fee) as fee,
YEAR(AVG(fee.Date)) as year,
MONTH(AVG(fee.Date)) as month
FROM Staff
JOIN fee ON staff.id = fee.staffid
ORDER BY fee.Date
GROUP BY staff.id, YEAR(fee.Date), MONTH(fee.Date)