fetching correct row according to time span - mysql

i have table for structure like this
empid fromdate todate office_ID
1 2012-03-01 2014-04-2 1
1 2014-04-03 ---- 2
2 2012-03-01 2014-04-2 2
3 2012-03-01 2014-04-2 1
from this table i want to fetch that at some month
for ex. for may 205 where was employee 1
for that i have designed query
select* from tbl_emp_office where (year(From_date)*100+ month(From_date)) < '201505'
but it is not giving correct answer for all users
if employee currently working at some office then todate will be not known hence it is null (this logic can be changed if you suggest some better )

If I understand you correctly, you want this:
select office_id
from employee_history
where year(fromdate) <= 2015
and month(fromdate) <= 5
and (
(month(todate) >= 5 and year(todate) >= 2015)
or todate is null
)
and empid = 1;
The query uses mysql functions to break the dates into year and month, and then makes sure that the month and year you are looking for is equal to or after their startdate, and that their todate is either null, or occurs after the month/year combo you are looking for.
This should also include offices they were in for a partial month.

Related

MySQL query to fetch all records between two given dates lied at least a day between two column dates

Employee table contains joinedDate and resignedDate column as date data type, need a mysql query to fetch worked employee records for a given between two dates.
Eg:
employee1 worked from 2014-01-01 to 2015-01-30
employee2 is working from 2014-07-01 to 2015-08-30
employee3 worked from 2014-12-01 to 2015-03-30
If I give start date as 2014-06-01 and end date as 2015-09-30, it should show all the three employee details.
If I give start date as 2015-02-01 and end date as 2015-02-30, it should show 2nd and 3rd employee details
Found query myself, Please improve my MySQL query if you find any
SELECT
* FROM
employeesTable WHERE (joinedDate <= '2014-06-01'
AND resignedDate >= '2014-06-01')
OR (joinedDate <= '2015-09-30'
AND resignedDate >= '2015-09-30');

Return rows between two dates

I have ItemsRent table,
ID | ParentID | SubID | StartDate | EndDate |
--------------------------------------------------------------------
1 | 100 | 102 | 2014-09-09 17:40:00 | 2014-11-09 17:40:00 |
2 | 70 | 73 | 2014-08-09 14:20:00 | 2014-12-09 13:40:00 |
The dates are in sql format.
My input dates are:
InputStartDate: 2014-09-09 18:00:00
InputEndDate: 2014-10-09 13:47:00
And i want to return the best row only of the dates are between two dates. So for example:
Lets call StartDate as S, and EndDate as E.
And input dates will be InputStartDate as IS, and InputEndDate as IE.
S E
|----------------|
IS IE
|XXXXXXX--------|
Any suggestions ?
This query will produce a result matching your illustration. It will find all rows where any time at all was spent between InputStartDate and InputEndDate, and output a modified date range that is clamped by InputStartDate and InputEndDate.
SELECT ID, ParentId, SubId,
MAX( InputStartDate, StartDate ) AS Date_Start,
MIN( InputEndDate, EndDate ) AS Date_End
FROM `itemsRent`
WHERE InputStartDate <= EndDate AND InputEndDate >= StartDate
Normally, I would say to use the BETWEEN operator, but since you are storing both the start and end dates in the table, this would get more complicated than it needs to be. If you assume that the start date being stored is before the end date, you only need to perform two checks.
SELECT * FROM `itemsRent` WHERE `StartDate` > 1410285600 AND `EndDate` < 1410356820
This verifies that the start date of the item takes place after the specified start date. The issue with this is that it does not check if it takes place before the end date. Instead of explicitly writing this check, you can make sure of this by checking that the item's end date takes place before the specified end date.
NOTE: Might cause issues if the start date does not occur before the end date. If this is a possibility, then you will need to explicitly write these checks. This would be a good case in which to use the BETWEEN operation.
Why not just pull out the max end date in the table as the high date?
SELECT *
FROM itemsRent
WHERE (InputStartDate BETWEEN startdate AND end date)
AND (InputEndDate BETWEEN startdate AND enddate);
Your query is currently looking for rows whose EndDate is earlier than your provided StartDate or after your provided EndDate. I don't think that is what you want.
If you want rows that both StartDate and EndDate are between your provided dates (lets call them your-start-date and your-end-date), your query should be something like:
SELECT * FROM `itemsRent` WHERE `StartDate` > your-start-date AND `StartDate` < your-end-date AND `EndDate` > your-start-date AND `EndDate` < your-send-date

Count number of Distinct days in query

We have a table that has a StartDate field which holds a type of datetime. There are thousands of records and I am looking for a way to find the number of days within a given result returned from this table. For instance, if my table had this data:
ID | StartDate
--------------
1 01/01/2013 09:34:54
2 01/01/2013 11:23:21
3 04/11/2013 14:43:23
4 04/11/2013 17:13:03
5 04/25/2013 18:02:59
6 07/21/2013 02:56:12
7 10/01/2013 19:43:10
Then the query should return 5 as the 2 dates on 01/01/2013 count as 1 and the same for 04/11/2013.
The only SQL I've been able to come up with is:
SELECT COUNT(DISTINCT(DATEPART(DAY, StartDate)))
FROM Stats
WHERE StartDate BETWEEN '01/01/2013' AND '12/31/2013' --This is just for filtering
But this returns 4 because it doesn't take the month into account.
Any help is appreciated.
You can CAST as date
SELECT COUNT(DISTINCT CAST(StartDate AS DATE))
FROM Stats
WHERE StartDate >= '20130101' AND StartDate < '20140101'
Also use an unambiguous date format such as yyyymmdd and >= < not BETWEEN.
Your current query would include the 31st December if there was a row with exactly the value 20131231 00:00:00 but not any with different times on that date. I doubt that is intentional.

Generate Monthly XML from a table containing date range

I have a table as -
test_table(booking_id, booking_description, start_date, end_date)
Sample Data -
1 | Some booking | 06/30/2013 | 08/01/2013
2 | Some new one | 08/05/2013 | 09/01/2013
3 | Some new two | 09/03/2013 | 09/05/2013
Now I want to generate a monthly xml file from using some java code (No problem in it, I would write), I would be passing the month and year (basically start and end date of the month) to mysql query and I want some table as -
month = 7, year 2013
1 | Some booking | 07/01/2013
1 | Some booking | 07/02/2013
...
Month = 9, year = 2013
2 | Some new one | 09/01/2013
| | 09/02/2013
3 | Some new two | 09/03/2013
...
I was looking to use a java loop from start date to end date and query mysql to find out whether this date comes in the date range or not, if it comes I would add the details else I would add blanks. But that is going to be horrible approach (will go for 30 times mysql look ups) and I am considering it as last option.
Is there any other way around with one or two mysql query and get the data in the format.
EDIT:
month = 7, year = 2013
Select *
from booking_details
where month(start_date) <= 7 and year(start_date) <= 2013 and
month(end_date) >= 7 and year(end_date) >= 2013
I developed this query but still not sure would it over all the possible scenarios.
Based on my understanding of the question you want something like this:
declare #date datetime
Select booking_id, booking_description, start_date --you don't indicate which date field you want in the results
from test_table
where (start_date between #date and date_add(#date, INTERVAL 1 MONTH))
or (end_date between #date and date_add(#date, INTERVAL 1 MONTH))
SQL is probably not exact, I know TSQL not MySQL but this should be close.

group by month of unix timestamp field

I'm trying to get my code to output in the following format:
january 2012 - 34
february 2012 - 23
where 34 and 23 would be a count of the total rows that fall within that month that have the id_dealership of 7. I need this to output all data for every month that an assignment was ever made.
The assignments table structure is as follows:
id_dealer (int)
date_assigned (int)
I've tried this but it does not work at all:
SELECT MONTH(date_assigned), YEAR(date_assigned), COUNT(*)
FROM assignments
GROUP BY MONTH(date_assigned), YEAR(date_assigned)
SELECT
MONTH(FROM_UNIXTIME(date_assigned)),
YEAR(FROM_UNIXTIME(date_assigned)),
COUNT(*)
FROM assignments
GROUP BY
MONTH(FROM_UNIXTIME(date_assigned)),
YEAR(FROM_UNIXTIME(date_assigned))
Your date_assigned column should be of type DATE. AFAIK MONTH works on date columns
and if you want the month name from a DATE column use : MONTHNAME(date_assigned)
try this query
SELECT
MONTH(FROM_UNIXTIME(date_assigned)),
YEAR(FROM_UNIXTIME(date_assigned)),
COUNT(*)
FROM assignments
GROUP BY 1,2
For people who would like to output a DATETIME rather than a month/year combo, here's another way to solve the problem. The benefit of using DATETIME is that it can easily be plugged into data visualization libraries and tools.
SELECT
LAST_DAY(FROM_UNIXTIME(date_assigned)),
COUNT(*)
FROM assignments
GROUP BY 1
ORDER BY 1 DESC
The LAST_DAY() function returns the last day of the month for a given DATE or DATETIME value. If you'd rather grab the first day, you could select this instead: ADDDATE(LAST_DAY(SUBDATE(FROM_UNIXTIME(date_assigned), INTERVAL 1 MONTH)), 1). It adds a day to the last date then subtracts a month.
The 1 values are column position integers -- shorthand so we don't have to type LAST_DAY(FROM_UNIXTIME(date_assigned)) any more than we need to (they start at 1, not 0).
Example output:
|-------------------------------------------|------------------|
| LAST_DAY(FROM_UNIXTIME(date_assigned)) | COUNT(*) |
|-------------------------------------------|------------------|
| September 30, 2020, 12:00 AM | 34 |
|-------------------------------------------|------------------|
| August 31, 2020, 12:00 AM | 23 |
|-------------------------------------------|------------------|