Could someone help me with this problem;
I have a table with a Value associated with a point_id and a timestamp.
tData
timestamp
point_id
Value
2022-10-28 08:00:00
carrots
8
2022-10-28 08:00:00
cabbage
6
2022-10-28 08:00:00
screw
255
2022-10-28 08:00:04
carrots
9
2022-10-28 08:05:11
cabbage
15
2022-10-28 08:55:16
screw
270
I have another table in which I have the point_id that I want to extract to transfert to another table
tDefAvgMinMax
point_id
carrots
cabbage
Lastly I have a table that looks like this
tReportAvgMinMax
Date
point_id
average
minimum
maximum
<value>
<value>
<value>
<value>
<value>
I run this query in order to extract the average, minimum and maximum and transfer it to the last table:
INSERT INTO tReportAvgMinMax (Date, point_id, average, minimum, maximum)
SELECT #Date, Def.point_id, AVG(T._VAL), MIN(T._VAL), MAX(T._VAL)
FROM tData T
RIGH JOIN tDefAvgMinMax Def
ON T.point_id = Def.point_id
WHERE T.Timestamp BETWEEN (CAST(#Date as datetime) + '00:00:00') AND (CAST(#Date as datetime) + '23:59:59")
GROUP BY def.point_id
This is working fine so far.
Now I need to add the timestamp of the minimum value and maximum value in the table tReportAvgMinMax. I tried different approach but I can't seem to get it to work. How can I acheive this?
Point_ID
Average
Timestamp_min
Minimum
Timestamp_max
Maximum
carrots
8.5
2022-10-28 08:00:00
8
2022-10-28 08:00:04
9
cabbage
10.5
2022-10-28 08:00:00
6
2022-10-28 08:05:11
15
Thank you
I tried to use a substatement like
SELECT Def.point_id, (SELECT ...) TimestampMin, MIN(T._VAL)
but the query is taking too long and does not give me the correct result.
I also tried with a LEFT JOIN and a ORDER BY to get the lowest value and return the timestamp but that gives me only the first point_id and the query is taking a long time to run
seconfHere is an example:
ID Datetime1 datetime2 (Results needed)
1 1/1/2010 7:54 1/2/2010 6:54 23
1 1/1/2010 7:54 1/4/2010 6:54 48
1 1/1/2010 7:54 1/5/2010 6:54 24
2 1/5/2010 11:00 1/8/2010 11:00 72
3 1/30/2010 23:05 2/1/2010 22:05 47
notice ID 1 in the first row it did a normal datediff but in the second and third row I need it to use the startdate of datetime2 and enddate of datetime2 of thee same ID.
turnaround time column is what is the output column I need, I only tried normal datediff but it just calculates the difference between datetime1 and datetime2. my problem is that it can be many IDs with a value of 1, so I need the datediff to dynamically update the startdate if another enddate exist for the same ID.
Im' working in a RDBMS 'Microsoft SQL server'
the code i tried is as followed:
select
*
,datediff(hh,datetime1,datetime2) as 'Turnaround time'
from
my_table
order by datetime1 asc
i hope this clears it out a little bit.
thank you in advance
the answer was Lead and Lag functions URL below:
https://www.databasejournal.com/features/mssql/lead-and-lag-functions-in-sql-server-2012.html
I have a table with time entries having start and end time. I want to get the time entries which are not there in the table.
Example: I have time entry having start time 08.00 - 09.00 and other for 10.20 - 11.00. I need a record which contains 09.00 - 10.19. As I need to do it for multiple occurrences, can anybody help me out to find this complex query?
i have a time range to show non occuring entries beteen 07.00 to 17.00 then it should return me 7.00 to 8.45 and 14.00 to 17.00
I lack reputation to do a comment (the comments by Mihai and TT were amazing and interesting), but a possible solution may be as simple as
SELECT a.endDT, Min(b.startDT)
FROM sched a, sched b
WHERE a.endDT<b.startDT
GROUP BY a.endDT
that will return for your sample data
2017-07-30 08:45:00.000 2017-07-30 09:30:00.000
2017-07-30 09:45:00.000 2017-07-30 10:30:00.000
2017-07-30 11:45:00.000 2017-07-30 13:15:00.000
2017-07-30 13:45:00.000 2017-07-30 14:00:00.000
However, as the comments of Mihai and TT point out, this will not get the time between say midnight and 8am, the first record.
I cannot tell what your sample data has to do with your description. But the problem seems to be solved by lag(). For the data you have provided:
select activity, prev_endtime as gap_start, starttime as gap_end
from (select t.*,
lag(endtime) over (partition by activity order by id) as prev_endtime
from t
) t
where starttime <> prev_endtime;
I should note that this will not work for all possible combinations of start times and end times. But, your time slots don't appear to overlap and they appear to be ordered by id, so this should work.
select date_add('2015-01-15',(7-dayofweek('2015-01-15')),"day"),
date_add('2015-01-15',(14-dayofweek('2015-01-15')),"day")
output of this query is
Row f0_ f1_
1 2015-01-17 00:00:00 UTC 2015-01-24 00:00:00 UTC
but i want to display the data as
sno date sum
1 2015-01-01 00:00:00 UTC 20(first month sum)
2 2015-02-01 00:00:00 UTC 30 (second month sum)
The STRFTIME_UTC_USEC has rich formatting of dates, the code for month names is %b, i.e.
select strftime_utc_usec(date_add('2015-01-15',
(7-dayofweek('2015-01-15')),"day"), "%Y-%b-%e"),
strftime_utc_usec(date_add('2015-01-15',
(14-dayofweek('2015-01-15')),"day"), "%Y-%b-%e")
results in
Row f0_ f1_
1 2015-Jan-17 2015-Jan-24
As an addendum, if you want to display the data from each month in multiple rows, you can use GROUP BY. There's an example here: Using a timestamp function in a GROUP BY.
I have a table where our product records its activity log. The product starts working at 23:00 every day and usually works one or two hours. This means that once a batch started at 23:00, it finishes about 1:00am next day.
Now, I need to take statistics on how many posts are registered per batch but cannot figure out a script that would allow me achiving this. So far I have following SQL code:
SELECT COUNT(*), DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
ORDER BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
which results in following
count day hour
....
1189 9 23
8611 10 0
2754 10 23
6462 11 0
1885 11 23
I.e. I want the number for 9th 23:00 grouped with the number for 10th 00:00, 10th 23:00 with 11th 00:00 and so on. How could I do it?
You can do it very easily. Use DATEADD to add an hour to the original registrationtime. If you do so, all the registrationtimes will be moved to the same day, and you can simply group by the day part.
You could also do it in a more complicated way using CASE WHEN, but it's overkill on the view of this easy solution.
I had to do something similar a few days ago. I had fixed timespans for work shifts to group by where one of them could start on one day at 10pm and end the next morning at 6am.
What I did was:
Define a "shift date", which was simply the day with zero timestamp when the shift started for every entry in the table. I was able to do so by checking whether the timestamp of the entry was between 0am and 6am. In that case I took only the date of this DATEADD(dd, -1, entryDate), which returned the previous day for all entries between 0am and 6am.
I also added an ID for the shift. 0 for the first one (6am to 2pm), 1 for the second one (2pm to 10pm) and 3 for the last one (10pm to 6am).
I was then able to group over the shift date and shift IDs.
Example:
Consider the following source entries:
Timestamp SomeData
=============================
2014-09-01 06:01:00 5
2014-09-01 14:01:00 6
2014-09-02 02:00:00 7
Step one extended the table as follows:
Timestamp SomeData ShiftDay
====================================================
2014-09-01 06:01:00 5 2014-09-01 00:00:00
2014-09-01 14:01:00 6 2014-09-01 00:00:00
2014-09-02 02:00:00 7 2014-09-01 00:00:00
Step two extended the table as follows:
Timestamp SomeData ShiftDay ShiftID
==============================================================
2014-09-01 06:01:00 5 2014-09-01 00:00:00 0
2014-09-01 14:01:00 6 2014-09-01 00:00:00 1
2014-09-02 02:00:00 7 2014-09-01 00:00:00 2
If you add one hour to registrationtime, you will be able to group by the date part:
GROUP BY
CAST(DATEADD(HOUR, 1, registrationtime) AS date)
If the starting hour must be reflected accurately in the output (as 9, 23, 10, 23 rather than as 10, 0, 11, 0), you could obtain it as MIN(registrationtime) in the SELECT clause:
SELECT
count = COUNT(*),
day = DATEPART(DAY, MIN(registrationtime)),
hour = DATEPART(HOUR, MIN(registrationtime))
Finally, in case you are not aware, you can reference columns by their aliases in ORDER BY:
ORDER BY
day,
hour
just so that you do not have to repeat the expressions.
The below query will give you what you are expecting..
;WITH CTE AS
(
SELECT COUNT(*) Count, DATEPART(DAY,registrationtime) Day,DATEPART(HOUR,registrationtime) Hour,
RANK() over (partition by DATEPART(HOUR,registrationtime) order by DATEPART(DAY,registrationtime),DATEPART(HOUR,registrationtime)) Batch_ID
FROM RegistrationMessageLogEntry
WHERE registrationtime > '2014-09-01 20:00'
GROUP BY DATEPART(DAY, registrationtime), DATEPART(HOUR,registrationtime)
)
SELECT SUM(COUNT) Count,Batch_ID
FROM CTE
GROUP BY Batch_ID
ORDER BY Batch_ID
You can write a CASE statement as below
CASE WHEN DATEPART(HOUR,registrationtime) = 23
THEN DATEPART(DAY,registrationtime)+1
END,
CASE WHEN DATEPART(HOUR,registrationtime) = 23
THEN 0
END