Okay, so I have a question about using columns in a case statement that might be null.
Again I have two tables the first looks like this UserActivity:
userID Action Time
1 25 12:00
1 10 12:01
1 12 12:35
1 6 13:54
2 10 6:47
2 42 6:48
3 8 11:54
etc.
But the second now looks like this UserSchedule:
userID startTime1 stopTime1 startTime2 stoptime2 startTime3 stopTime3
1 07:00 09:00 11:00 12:00 14:30 16:30
2 11:00 12:30 14:00 15:30
3 14:00 15:00
etc.
So I need to be able to evaluate when in relation to all of those start and stop times an Action took place. Some users will have up to 5 start/stop times in a day. Some will only have one.
This code was given to me to resolve an earlier issue by #Adam Wengler, and it works great if there is only one start and stop time. I'm unsure how to include the logic to test against each of the 5 potential start/stop columns and ignore them if they are empty.
UPDATE ua
SET ua.TimeStatusId = CASE
WHEN ua.Time >= us.Schedule_Start
AND ua.Time <= us.Schedule_stop THEN 1
WHEN ua.Time >= DATEADD(HOUR, -1, us.Schedule_Start)
AND ua.Time <= us.ScheduleStart THEN 0
WHEN ua.Time >= us.Schedule_Stop
AND ua.Time =< DATEADD(HOUR, 1, us.Schedule_Stop)
THEN 2
ELSE 3
END
FROM dbo.UserActivity AS ua
INNER JOIN dbo.userSchedule AS us ON ua.UserId = us.UserId
You can use the IsNull() function to resolve your issue
Related
im trying to fetch the data between two times, i.e., morning (7:30AM to 7:30PM) evening (7:30PM to 7:30AM).
required only hour based output.{ > 7:30 < 19:30 as morning and > 19:30 < 7:30 as night)
Please suggest the query
Tablename: data
----------------
created_date services_name id
28-08-2022 18:54 KANE 1
28-08-2022 19:00 BAPLO 2
28-08-2022 23:22 BAPLO 3
28-08-2022 23:40 VLOTLS 4
29-08-2022 00:02 DELLP 5
29-08-2022 00:42 SECON 6
29-08-2022 02:00 BAPLO 7
29-08-2022 03:00 PRODC 8
29-08-2022 05:14 DELLP 9
29-08-2022 05:30 SECON 10
29-08-2022 05:42 SECON 11
im using below command to fetch output
SELECT
CONCAT( HOUR(created_date), ' to ', CONCAT( HOUR(created_date), ':59:59' ) ) as time_frame,
COUNT(*)
FROM
data
GROUP BY
DATE(created_date),
HOUR(created_date)
ORDER BY
DATE(created_date),
HOUR(created_date)
Out as below
0 to 0:59:59 2
2 to 2:59:59 1
3 to 3:59:59 1
5 to 5:59:59 3
18 to 18:59:59 1
19 to 19:59:59 1
23 to 23:59:59 2
But i required as
morning ( between 07:30 to 19:30) count is 2
evening ( between 19:30 to 07:30) count is 9
You can perform a UNION to get two separate counts, one for morning times and one evening times. Within the WHERE clause, you can convert created_date to a time format using the TIME() data type and then plug in your morning and evening times within the BETWEEN condition.
Note that you have to use the NOT operator to negate the BETWEEN operator for the evening count because BETWEEN works within a range (small to large 0..1, not large to small 1..0) so the NOT operator will essentially get everything else outside of the morning BETWEEN range.
SELECT 'Morning' as time_frame, COUNT(*) AS `count` FROM temp
WHERE TIME(created_date)
BETWEEN '07:30:00' AND '19:30:00'
UNION
SELECT 'Evening' as time_frame, COUNT(*) AS `count` FROM temp
WHERE TIME(created_date)
NOT BETWEEN '07:30:00' AND '19:30:00'
Output:
time_frame
count
Morning
2
Evening
9
See Fiddle.
I have one table bibles that having two columns only i.e. is below:-
id chapter_name
1 Mathews 1
2 Mathews 2
3 Mathews 3
4 Mathews 4
... ....
... ....
364 Revelation 22 //Total Records only 364 fixed. that will not increase
Bible Scheduling starts from 5 sept 2021 for 3 years and ends on 31 Aug 2024 i.e basically bible repeats three time in 3 years.
Now Suppose today date is 8 Sept 2021
id chapter_name date_1 date_2 date_3
1 Mathews 1 2021-09-05 2022-09-04 2023-09-03
2 Mathews 2 2021-09-06 2022-09-05 2023-09-04
3 Mathews 3 2021-09-07 2022-09-06 2023-09-05
4 Mathews 4 2021-09-08 2022-09-07 2023-09-06
... ....
... ....
So now requested date is 8 spet 2021 i want to fetch the 4th record Mathews 4 and now suppose today date is 6 sept 2022 and now want to fetch the 3 row Mathews 3.
Note : these date columns are not stored in database. i have only two columns id, chapter_name.. Reason for not storing the dates because after three years i need to update again that dates to make scheduling works. Is there any way to fetch the rows?
Below answer works fine but I have two types of Bibles that starts from Id 1 to 364 another starts from 365 to 1456... 1st case
1 to 364 works.. but 365 to 1456 not works
If I understand correctly, then logic you want is:
where dateadiff(?, '2021-09-05') % 364 = id - 1
The ? is a parameter for the date you pass in.
You can start with some anchor date in the past, 2020-09-06 will do.
The id in your table is a number of days between the anchor date and the current date mod 364 (the number of rows in your table).
SELECT
id, chapter_name
FROM bibles
WHERE
id = DATEDIFF(CURRENT_DATE(), '2020-09-06') % 364 + 1
;
The DATEDIFF(CURRENT_DATE(), '2020-09-06') function returns the number of days between the current date and the anchor date 2020-09-06, i.e. the number of days between the date when the schedule started and now. This number can grow larger than 364 (the number of rows in your table). To "wrap" this number back to 0 when it is larger than 364 we use the modulo division (mod) or % operator. And then add 1, because ids in your table start with 1 (if they started with 0 you didn't have to add 1).
Try to run this query replacing the CURRENT_DATE() with your sample dates 2021-09-08 and 2022-09-06.
SELECT DATEDIFF('2021-09-08', '2020-09-06') % 364 + 1;
returns 4 (4th row)
SELECT DATEDIFF('2022-09-06', '2020-09-06') % 364 + 1;
returns 3 (3rd row)
It means that if you run the full query with the CURRENT_DATE() function on 2021-09-08 it will return a row with id=4. When you run the query on 2022-09-06 it will return a row with id=3.
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
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:
I am using Access 2010. My SQL knowledge is limited and I haven't been able to figure out how to code the following rules.
I have a datetime column that I sort by datetime and then group by date (using group by int(datetime).
Now I want to select records within each date up to and including the point a condition is met. Once condition is met, then that record with all preceding records will be returned as the record set for that day. Records for that date following a matching condition will be ignored.
My data has:
Trade DateTime Points CumPoints
1 11/20/2015 9:31 AM 2 2
2 11/20/2015 9:49 AM 1 3
3 11/20/2015 9:55 AM 1.25 4.25
4 11/20/2015 10:20 AM -1.5 2.75 -- record ignored
5 11/20/2015 10:21 AM -0.75 2 -- record ignored
6 11/20/2015 10:36 AM 5.25 7.25 -- record ignored
1 11/23/2015 9:30 AM 2 2
2 11/23/2015 10:07 AM -1.25 0.75
3 11/23/2015 10:29 AM 0.5 1.25
4 11/23/2015 11:07 AM -1.25 0
5 11/23/2015 11:23 AM -0.25 -0.25 -- record ignored
6 11/23/2015 12:53 PM -1 -1.25 -- record ignored
So if my rules are that once Cum-points >=4 or if Cum-points <= 0 after 11:00 AM then those records are returned. In the above example the query should return the first 3 records for the first date and the first 4 records for the 2nd date.
Any assistance will be appreciated.
That could be like this:
Select
DateValue([DateTime]) As [Date], Points, CumPoints
From
YourTable
Having
(CumPoints >= 4)
Or
(TimeValue([DateTime]) > #11:00:00 AM#
And
CumPoints <= 0)
Group By
DateValue([DateTime]) As [Date], Points, CumPoints
You will have to adjust as your sample data don't correlate with your description of the conditions.