Converting the result of a MySQL table as per requirement - mysql

The mysql table we work on has data in the following format:
entityId status updated_date
-------------------------------
1 1 29/05/2017 12:00
1 2 29/05/2017 03:00
1 3 29/05/2017 07:00
1 4 29/05/2017 14:00
1 5 30/05/2017 02:00
1 6 30/05/2017 08:00
2 1 31/05/2017 03:00
2 2 31/05/2017 05:00
.
.
So every entity id has 6 statuses, and every status has an update datetime. Each status has an activity attached to it.
For example 1 - Started journey
2 - Reached first destination
3 - Left Point A, moving towards B. etc
I need to get an output in the below format for specific entity id eg 3 and 4. I need the time for status 3 and 4 independently.
entity_id time_started_journey time_reached_first_destination
(update time of status 3) (update time of status 4)
--------------------------------------------------------------
1 29/05/2017 7:00 29/05/2017 14:00
2 30/05/2017 7:00 30/05/2017 16:00
Later I need to calculate the total time which would be the difference of the two.
How can I achieve the desired result using mysql.
I tried using Union operator but cannot do it separate columns.
Also, tried using case when operator with the below query but failed.
select distinct entityid,
(case status when 3 then freight_update_time else 0 end)
as starttime,
(case status when 4 then freight_update_time else 0 end) as endtime
from table ;
Can anyone throw light on this?

Conditional aggregation is one way to return a resultset that looks like that.
SELECT t.entityid
, MAX(IF(t.status=3,t.updated_date,NULL)) AS time_started_journey
, MAX(IF(t.status-4,t.updated_date,NULL)) AS time_reached_first_destination
FROM mytable t
WHERE t.status IN (3,4)
GROUP BY t.entityid
ORDER BY t.entityid
This is just one suggestion; the specification is unclear about what the query should do with duplicated status values for a given entityid.
There are other query patterns that will return similar results.

My query in MySQL
SELECT
e3.updated_date AS sta3,
e4.updated_date AS sta4
FROM
`prueba` AS e3
LEFT JOIN prueba AS e4
ON
e3.entityId = e4.entityId AND e4.status = 4
WHERE
e3.status = 3
OUTPUT:

Related

MySql - count records since last time it was X o'clock

I need to count records created since it was last 9:00am.
so at 8:59am I need to count all records since yesterday at 9:00am and at 9:01am I will need to count since today at 9:00am,
data sample
ID | created
----------------------------------
1 | 2018-11-13 17:00
2 | 2018-11-13 09:00
3 | 2018-11-13 08:01
4 | 2018-11-12 13:00
5 | 2018-11-11 17:31
running the query at 13-11-2018 8:59am should return 2 (rows 3,4)
running the query at 13-11-2018 9:01am should return 1 (rows 2)
the query I'm looking for should be something like:
SELECT count(id) FROM myTable WHERE created > "TIME_SINCE_9AM()"
any help?
I figured out a solution, I hoped for a prettier query but it works...
I'm using IF statement to determine if right now is before 9am or after and running count on records accordingly, (the H var is for testing purposes, if you put 18 in there it works since last 18:00)
SET #H = "9";
SELECT
IF (TIMEDIFF(NOW(), SUBDATE(CURDATE(),INTERVAL (-#H) HOUR))<0,
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H+24) HOUR) THEN 1 ELSE 0 END),
SUM(CASE WHEN created>SUBDATE(CURDATE(),INTERVAL (-#H) HOUR) THEN 1 ELSE 0 END)
) counter
FROM mytable

get value from mysql database using month no and week no

Is it possible to retrieve the records from the table using month no and week no
for example I have a table
CustomerID CustomerName date(data type date)
1 sam 2016-06-1
2 dam 2016-06-2
3 kam 2016-06-8
4 ram 2016-06-9
4 ram 2016-07-8
how can i retrieve the month no 6 and week no 1 records
after the select query expected result is
CustomerID CustomerName date
1 sam 2016-06-1
2 dam 2016-06-2
it will give 2 records because date 1 and 2 fall under first week
if question is not clear please reply
thanks !
You can use month and week functions. Documentation here.
select * from table where month(`date`) = 6 and week(`date`) = 1

Employee available for task between a date range

I have been working on a employee work management project and I am a little stuck. I have 3 tables:
1: employees
empid, empFirst empLast
1 jon smith
2 mark road
3 jane hall
2: holiday
id employee id datestart dateend
1 2 2015-08-07 2015-08-12
2 3 2015-07-4 2015-07-11
3 2 2015-07-20 2015-07-24
3: Task Assigned
id taskid assignedTo(userid) startTask endTask
1 1 1 2015-07-10 2015-07-14
2 2 2 2015-07-29 2015-07-29
3 2 3 2015-07-18 2015-07-30
4 3 2 2015-08-30 2015-09-03
5 4 2 2015-09-10 2015-09-03
I'm not sure how to go about querying the tables to see who is available for a task in a date range (multiple user assigned to the same task). I have a query which I would here:
so if you take the holiday table out if the equation and just run the query below
SELECT employees.empId, employees.empFirst, employees.empLast
FROM employees
LEFT JOIN taskassigned
ON employees.empId = taskassigned.assignedTo
WHERE taskassigned.assignedTo IS NULL or
not (taskassigned.startTask BETWEEN '2015-07-29 14:30:00' AND '2015-07-29 18:30:00'
or taskassigned.endTask BETWEEN '2015-07-29 14:30:00' AND '2015-07-29 18:30:00')
the result I get is:
empId empFirst empLast
1 jon smith (he is available)
2 mark road
2 mark road
As you can see Mark is not available on this date (in the task table).
I would like the query the holiday table first to see if they are on holiday then the task table to see if they already have a task on the date range then the result to show me how is available for the task.
I can't test this at the moment, but try:
SELECT employees.empId, employees.empFirst, employees.empLast
FROM employees
LEFT JOIN taskassigned
ON employees.empId = taskassigned.assignedTo
LEFT JOIN holiday
ON employees.empId = holiday.employeeId
WHERE (
taskassigned.assignedTo IS NULL
OR (
'2015-07-29 14:30:00' NOT BETWEEN taskassigned.startTask AND taskassigned.endTask
AND '2015-07-29 18:30:00' NOT BETWEEN taskassigned.startTask AND taskassigned.endTask
)
)
AND (
holiday.employeeId IS NULL
OR (
'2015-07-29 14:30:00' NOT BETWEEN holiday.dateStart AND holiday.dateEnd
AND '2015-07-29 18:30:00' NOT BETWEEN holiday.dateStart AND holiday.dateEnd
)
)
This would check to see if the specified start date doesn't fall inbetween the assigned task's start or end date, and if the specified end date doesn't fall inbetween the assigned task's start or end date, and then do the same for holidays.
Hi I don't have the right tools to test right now but here is what you can try to do:
when using date comparison:
try to convert/cast to DATE (make sure time is not included) to make sure the result is correct.
as far as I know when using between the start and end date are also included (maybe in some RDMS feature)
Also for including holiday, what you can do is like this (either):
first join with holiday table first then with the result join again with the task assigned table.
or
first join with task assigned table then with the result join again with the holiday table
Sorry for no code included, as I have no time to setup.

how to compare the current record to the next in the same table in terms of 'datetime' in MySQL?

Problem: I’m going to explain this problem using the Sakila sample database and it data so it is easier for you. Ok, so my question is how can I compare the current record to the next in the same table in terms of 'datetime'. This is how the table looks like:
payment_id customer_id staff_id rental_id amount payment_date last_update
1 1 1 76 2.99 25/05/2005 11:30:37 15/02/2006 22:12:30
2 1 1 573 0.99 28/05/2005 10:35:23 15/02/2006 22:12:30
3 1 1 1185 5.99 15/06/2005 00:54:12 15/02/2006 22:12:30
4 1 2 1422 0.99 15/06/2005 18:02:53 15/02/2006 22:12:30
5 1 2 1476 9.99 15/06/2005 21:08:46 15/02/2006 22:12:30
Using the above explanation in this sample, for each ‘staff_id’, how can I compare the current row with the next (using ‘payment_date’ for current and next), so it brings only the pair of records where the amount of the current record is the same as the next (something like current.amount = next.amount). This means that each record should be compared to the next of the same ‘staff_id’, and so on.
I’m currently using this query, which do the job, but it takes for ever. I know it works good because I setted LIMIT 3 and it brought the correct ones (you can test it as well if you have the Sakila sample database):
SELECT * FROM payment a
JOIN payment b ON a.staff_id = b.staff_id AND a.payment_date > b.payment_date AND a.amount = b.amount
LEFT JOIN payment c ON a.staff_id = c.staff_id AND c.payment_date < a.payment_date AND c.payment_date > b.payment_date
WHERE c.payment_id IS NULL
LIMIT 3;
Could you please help me?

Finding dates within one year of each other

I am trying to determine the number of employees who left the company within 1 year of being hired:
SELECT
Min(O896IA_VEMPPRSA.EMP_RHR_DT) AS MinOfEMP_RHR_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) AS MaxOfREC_EFF_STT_DT,
O896IA_VEMPPRSA.SYS_EMP_ID_NR
FROM O896IA_VEMPPRSA
INNER JOIN O867IA_VJOBHST
ON O896IA_VEMPPRSA.SYS_EMP_ID_NR = O867IA_VJOBHST.SYS_EMP_ID_NR
WHERE
O867IA_VJOBHST.EMP_ACN_TYP_CD="TER"
GROUP BY
O896IA_VEMPPRSA.SYS_EMP_ID_NR;
EMP_RHR_DT is the original hire date, and REC_EFF_STT_DT is the date they quit/were fired. Again I need the REC_EFF_STT_DT to be within 365 days of the EMP_RHR_DT. Any thoughts?
Example of RHR Date Changes. IN some cases there will only be one job but still a negative days worked, in other cases it is because it is selecting the wrong job.
Job MinOfEMP_RHR_DT MaxOfREC_EFF_STT_DT daysworked SYS_EMP_ID_NR
abc1 10/24/2012 4/15/2013 173 123456
abc1 4/25/2013 4/13/2013 -12 234567
abc3 7/8/2013 1/4/2013 -185 891234
abc4 7/8/2013 7/29/2013 21 891234
Assuming O896IA_VEMPPRSA is master table and O867IA_VJOBHST is detail table with the following data:
O896IA_VEMPPRSA:
ID EMP_RHR_DT SYS_EMP_ID_NR Empname
1 8/10/2012 1 John
2 10/10/2012 2 Matthew
O867IA_VJOBHST:
ID SYS_EMP_ID_NR EMP_ACN_TYP_CD REC_EFF_STT_DT
1 1 Married 1/1/2003
2 1 Became dad 8/1/2003
3 1 TER 9/10/2013
5 2 Remarried 1/1/2003
6 2 Remarried 8/1/2003
7 2 TER 9/10/2013
You could do this to get the number of days worked:
SELECT
Min(O896IA_VEMPPRSA.EMP_RHR_DT) AS MinOfEMP_RHR_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) AS MaxOfREC_EFF_STT_DT,
Max(O867IA_VJOBHST.REC_EFF_STT_DT) - Min(O896IA_VEMPPRSA.EMP_RHR_DT) as daysworked,
O896IA_VEMPPRSA.SYS_EMP_ID_NR
FROM O896IA_VEMPPRSA
INNER JOIN O867IA_VJOBHST
ON O896IA_VEMPPRSA.SYS_EMP_ID_NR = O867IA_VJOBHST.SYS_EMP_ID_NR
WHERE
O867IA_VJOBHST.EMP_ACN_TYP_CD="TER"
GROUP BY
O896IA_VEMPPRSA.SYS_EMP_ID_NR;
HAVING
(Max(O867IA_VJOBHST.REC_EFF_STT_DT) - Min(O896IA_VEMPPRSA.EMP_RHR_DT)) < 365;
The solution is with the datediff function. You will end up with a constraint like:
WHERE DateDiff("yyyy",hiringDate, endingDate)<1
Please check the exact syntax for the DateDiff function in the MS-Access help