Is this query possible? - mysql

Here is my table:
table employee (
char(50) name
datetime startdate
datetime finishdate
}
Assume that at least one employee started everyday since the start of the business so that
select distinct startdate from employee
would return every day the business was open. I've already provided a query to get every day the business was open, but would it be pair each day with the number of employees that were employed on that day? Essentially I am asking whether it is possible to count the number of employees for which (startdate <= day AND finishdate >= day) is true for each day and return that relation in one query.

SELECT x.startDate, COUNT(e.startDate)
FROM (SELECT DISTINCT startDate FROM employee) AS x
INNER JOIN employee AS e
ON x.startDate BETWEEN e.startDate AND e.finishDate
GROUP BY x.startDate

SELECT e1.startdate, COUNT(*) AS num_employed_on_date
FROM employee e1 INNER JOIN employee e2
ON e1.startdate BETWEEN e2.startdate and e2.finishdate
GROUP BY e1.startdate

'startdate' holds the date an employee joined the company.
If you get MIN for startdate and MAX for finishdate, you'll have the entire span of time the company was open.
What you suggested would return every date at least one employee joined the company / started working.

Related

counting occurrences between dates of different date intervals

I have a query that give me a table like this:
Person | Date_IN | Date_OUT | Structure
During a year a person ENTER and EXIT many times, ENTER and EXIT could be also the same day.
I'd like to count, for a specific day of year, how many person were IN each structure.
The final goal is to have, for a given period (1st march --> 31st march), the sum of total person for each day for each structure.
I believe the following would work. It assumes that you have a table of dates (consists of one column which contains all the dates between 1950 and 2050) and you simply join it with the person check in/out table:
SELECT dates.date, Structure, COUNT(DISTINCT Person) Persons_on_That_Date
FROM dates
LEFT JOIN turndata ON dates.date BETWEEN Date_IN AND Date_OUT
WHERE dates.date BETWEEN '2018-03-01' AND '2018-03-31'
GROUP BY dates.date, Structure
ORDER BY Structure, dates.date
Demo Here
Note: the above assumes that the out date is inclusive (the person is counted as inside on that date). If out date is exclusive then the ON clause becomes:
... ON Date_IN <= dates.date AND dates.date < Date_OUT
Please use below query, data is grouped by structure for particular timeframe.
SELECT structure, COUNT(DISTINCT person) as no_of_person
FROM table_name
WHERE DATE(Date_IN) BETWEEN '2018-08-01' AND '2018-08-31'
GROUP BY structure
You say there can be no multiple date_in for the same day and person, because a person is in at least one day. So for a given date we only must look at the latest event per person until then to see whether the person is/was in that day.
These are the steps:
create a data set for the requiered days on-the-fly
join with the table and get the last date_in until that day per person
join with the table again to get the last records
aggregate per day and count persons present
This is:
select
data.day
sum(t.date_in is not null and (t.date_out is null or t.date_out = data.day)) as count_in
from
(
select days.day, t.person, max(t.date_in) as max_date_in
from (select date '2018-03-01' as day union all ...) days
left join t on t.date_in <= days.day
group by days.day, t.person
) data
left join t on t.person = data.person and t.date_in = data.max_date_in
group by data.day
order by data.day;

Query Between two date fields

I have one table of employees with a column called Hire Date. And I have another table of orders and every order has a date when it was processed.
Now I want to figure out how many orders this employee made in the first 30 days from his hire date. I made a query with DateAdd function in access and made a column with all employees 30 days after hire date, now I want to make a query of orders between hire date and 30 days after hire date.query from 30 days after hire date
Assume Employees table has EmpCode and Orders table has EmpCode too
It will be something like this
SELECT *
FROM Orders INNER JOIN Employees ON Orders.EmpCode = Employees.EmpCode
WHERE EmpCode = 'ABCD' AND DateAdd ( d, 30, Employees.HireDate) > Orders.OrdDate
Expand your query to include the EmployeeId. Then it could be:
Select
YourQuery.FirstName, YourQuery.LastName, Count(OrderTable.*) As OrderCount
From
YourQuery,
OrderTable
Where
OrderTable.EmplyoyeeId = YourQuery.EmplyoyeeId
And
OrderTable.OrderDate Between YourQuery.[Hire Date] And YourQuery.[30 days after]
Group By
YourQuery.FirstName,
YourQuery.LastName

Select from 2 tables only the new entries in table 2

I got 2 tables, Customers and Payment. I'm trying to select only the new customers that have payments in the specified month and year, and no previous payments in another month.
table Customer
id - name
table Payment
id - id_customer - month - year - amount
SELECT * FROM customer, payment
WHERE Customer.id = Payment.id_customer
AND month = '$month'
AND year = '$year'
That gets me all the payments in a specific month and year, but I don't know how to exclude all the customers that had other previous payments.
Thank you for your time.
I don't think that you could achieve this without a third table. What you can do is create a third table with all the ids that you have selected in query and update it every time you run a select query.
Then the below query might work:
SELECT * FROM customer c, payment p WHERE c.id = p.id_customer
AND month = '$month'AND year = '$year'AND p.id NOT IN (SELECT id FROM
third_table)
Hope it answers your question.
To get the first date of payment, use GROUP BY. But, you will have to convert the value to something like a date first:
SELECT p.id_customer, MIN(CONCAT_WS, '-', p.year, p.month)) as first_yyyymm
FROM payment p
GROUP BY p.id_customer;
You should store the payment date as a date.

Finding those employees who had joined in 1st quarter of the year

Finding record of those employees who had joined in 1st quarter of the year,I have tried the following query but I want the query without specifying the explicit date.
select * from employee where DOJ between '2015-01-01' and '2015-03-31';
Use quarter
select * from employee where year(DOJ) = 2015 and quarter(DOJ) = 1;

Advanced MySQL Query select and compare time in one field

Employees
EmpID : int(10)
Firstname: varchar(100)
Lastname: varchar(100)
HireDate: timestamp
TerminationDate: timestamp
AnnualReviews
EmpID: int(10)
ReviewDate: timestamp
What is query that returns each employee and for each row/employee include the greatest number of employees that worked for the company at any time during their tenure and the first date that maximum was reached.
So far, this is my query:
select *, (select count(empid) from employees where terminationdate between t.hiredate and t.terminationdate)
from employees as t
group by empid
What you have is close.
But there's more work to do.
We'd to work out the conditions that determine how many employees were "working" at any point in time (i.e. at a given timestamp value.) The condition I'd check:
HireDate <= timestamp < TerminationDate
We'd need to extend that comparison, so that a NULL value for TerminationDate would be handled like it were a point in time after the timestamp value. That's easy enough to do.)
HireDate <= timestamp AND ( timestamp < TerminationDate OR TerminationDate IS NULL
So, something like this:
SELECT COUNT(1)
FROM Employees e
WHERE ( :timestamp >= e.HireDate )
AND ( :timestamp < e.TerminationDate OR e.TerminationDate IS NULL)
That "count" value would remain the same, and would only change for a "hire" or "terminate" event.
If we got a distinct list of all timestamps for all "hire" and "terminate" events, we could get the number of employees at that point in time.
So, this query would give us the employee count every time the employee count might change:
SELECT t.ts AS `as_of`
, COUNT(1) AS `employee_count`
FROM Employees e
JOIN ( SELECT t.TerminationDate AS ts
FROM Employees t
WHERE t.TerminationDate IS NOT NULL
GROUP BY t.TerminationDate
UNION
SELECT h.HireDate AS ts
FROM Employees h
WHERE h.HireDate IS NOT NULL
GROUP BY h.HireDate
) t
ON ( t.ts >= e.HireDate )
AND ( t.ts < e.TerminationDate OR e.TerminationDate IS NULL)
GROUP BY t.ts
We could use that result (as an inline view) and join that to particular Employee, and get just the rows that have an as_of timestamp that matches the period of employment for that employee. Then just pulling out the maximum employee_count. It wouldn't be difficult to identify the earlier of multiple as_of dates, if that maximum employee_count occurred multiple times.
(The wording of the question leaves open a question, the "earliest date" ever that the employee count met or exceeded the maximum that occurred during an employees tenure, or just the earliest date within the employees tenure that the maximum was reached. It's possible to get either result.)
That's just one way to approach the problem.