I am getting 0 on executing the following statement:
SELECT DATEDIFF(mi,'1970-01-01 00:00:00','1970-01-01 00:00:01') * CONVERT(BIGINT,60)*1000 as BidTicks
Whereas I get 6000 on executing this:
SELECT DATEDIFF(mi,'1970-01-01 00:00:00','1970-01-01 00:01:01') * CONVERT(BIGINT,60)*1000 as BidTicks
What are my options?
You need to use s or ss for your expected output .
select DATEDIFF(s,'1970-01-01 00:00:00','1970-01-01 00:00:01') * CONVERT(BIGINT,60)*1000 as BidTicks
it will prodece :
60000
To return the difference in seconds as the first argument in your query, you'll want to use seconds as the argument, which is an s:
select DATEDIFF(s,'1970-01-01 00:00:00','1970-01-01 00:01:01')
Basically, your query is asking for the number of minutes between the two. Your first query returns 0, the second returns 1.
Therefore 0 * 60 * 1000 = 0 and 1 * 60 * 1000 = 60000
Try the following:
select DATEDIFF(s,'1970-01-01 00:00:00','1970-01-01 00:01:01')
-- * convert(BIGINT,60) wasn't sure if this was necessary still
* 1000 as BidTicks
Use s or ss instead of mi
select DATEDIFF(s,'1970-01-01 00:00:00','1970-01-01 00:00:01') * CONVERT(BIGINT,60)*1000 as BidTicks
datepart | Abbreviations
------------+---------------
hour | hh
minute | mi, n
second | ss, s
millisecond | ms
microsecond | mcs
nanosecond | ns
Related
I have a table which stores a set of events whose schema can be simplified for this example to
CREATE TABLE events (
id INTEGER PRIMARY KEY,
time INTEGER NOT NULL,
data BLOB
);
CREATE INDEX by_time ON events(time);
Given a time interval min to max, I want to get the number of events in each 1-hour interval between min and max (concrete example below).
The most obvious way to achieve this that I can think of is to compute the required intervals in my code and then for each one run the query
SELECT count(*) FROM events WHERE ? <= time AND time < ?;
Is there a faster way to achieve this by making SQLite deal with splitting the interval into smaller chunks?
If this makes the solution simpler, we can assume min and max are exactly at the start/end of an hour interval.
Example
Suppose events contains events with times
100, 200, 1600, 3000,
3800, 4000,
7400,
15000, 15200, 17000,
20400,
22300, 23000
Then I would want a query with min = 3600, max = 21600 to return something like
start | end | count
-------------------
3600 | 7200 | 2
7200 | 10800 | 1
10800 | 14400 | 0
14400 | 18000 | 3
18000 | 21600 | 1
It doesn't matter exactly what the format of the output is as long as it contains the required counts and a way to identify which interval they refer to.
You can use a recursive CTE to get the time intervals and then LEFT join the table to aggregate:
WITH
cte(min, max) AS (SELECT 3600, 21600),
intervals AS (
SELECT min from_time, min + 3600 to_time, max
FROM cte
WHERE min + 3600 <= max
UNION ALL
SELECT to_time, to_time + 3600, max
FROM intervals
WHERE to_time + 3600 <= max
)
SELECT i.from_time, i.to_time,
COUNT(e.id) count
FROM intervals i LEFT JOIN events e
ON e.time >= i.from_time AND e.time < i.to_time
GROUP BY i.from_time, i.to_time;
See the demo.
I have a table that stores a sensor temperature readings every few seconds
Sample data looks like this
nId nOperationId strDeviceIp nIfIndex nValue nTimestamp
97 2 192.168.99.252 1 26502328 1593828551
158 2 192.168.99.252 1 26501704 1593828667
256 2 192.168.99.252 1 26501860 1593828788
354 2 192.168.99.250 1 26501704 1593828908
452 2 192.168.99.250 1 26501692 1593829029
I want to have the average temperature per device so I ran the following query
select strDeviceIp, AVG(CAST(nValue as bigint)) as val1
from myTable
where nOperationId = 2 and nTimestamp >= 1593828600 and nTimestamp <= 1593838600
group by strSwitchIp;
Where I can pass the time range I want.
My issue is that this gives me total average but I want steps or range
I want to achieve that instead of one line I'll get all the values in a range/step of say 5 minutes as a row.
P.S. I'm trying to show a graph.
Running the following query I get
strSwitchIp average
192.168.99.252 26501731
But I would like to get
strSwitchIp average timestamp
192.168.99.252 26201731 1593828600
192.168.99.252 26532731 1593828900
192.168.99.252 24501721 1593829200
192.168.99.252 26506531 1593829500
In this example I would like to get a row every 300 seconds, per device.
Since your nTimestamp is number of seconds, you can simply add it to the GROUP BY. Division by 300 gives you 300 second (5 minute) intervals. In SQL Server / is integer division, which discards the fractional part.
select
strSwitchIp
,AVG(CAST(nValue as bigint)) as val1
,(nTimestamp / 300) * 300 AS Timestamp
from myTable
where
nOperationId = 2 and nTimestamp >= 1593828600 and nTimestamp <= 1593838600
group by
strSwitchIp
,nTimestamp / 300
;
nTimestamp / 300 gives an integer, a number of 5-minute intervals since 1970. / discards here the fractional part.
When this number is multiplied back by 300, it becomes again the number of seconds since 1970, but "rounded" to the nearest 5-minute interval. Just as you showed in the question in the expected result.
For example:
1593828667 / 300 = 5312762.2233333333333333333333333
discard fractional part
1593828667 / 300 = 5312762
5312762 * 300 = 1593828600
So, all timestamps between 1593828600 and 1593828899 become 1593828600 and all values for these timestamps are grouped into one row and averaged.
you ca use partition like this:
select strDeviceIp, AVG(CAST(nValue as bigint)) as val1,
ROW_NUMBER() over(partition by nTimestamp order by nTimestamp desc) as ROW_NO from AmyTable) Q where q.ROW_NO%5=0
....
I'm creating a query to multiply a time by a number.
The time is the result of a query of the annual working hours of a person. The purpose is calculate the 25% then I want to multiply the time by 0.25
Example:
Time1: 100:00:00
[format H:M:s]
For this I've tried this query:
SELECT '100:00:00'::time * 0.25
PostgreSQL returns:
ERROR: the time / date value is out of range: «100: 00: 00»
LINE 2: SELECT '100: 00: 00' :: time * 0.25
The error is clear. My conversion of the time is out of range because the time object only is valid to 24 hours. In this case is working fine:
SELECT '24:00:00'::time * 0.25
Result:
"06:00:00"
Someone have any idea?
Time values are limited to 24 hours. You can do the calculation using other units. For instance, the following translates this to seconds:
select 0.25 * ( (string_to_array('100:00:00', ':'))[1]::int*60*60 +
(string_to_array('100:00:00', ':'))[2]::int*60 +
(string_to_array('100:00:00', ':'))[3]::int
) as num_seconds
Note that you also cannot represent the result as a time
You can use an INTERVAL, as in:
select interval '100 hours 0 minutes 0 seconds' * 0.25
or:
select interval '100:00:00' * 0.25
or:
select '100:00:00'::interval * 0.25
The result (for all of them):
?column?
--------
25:00:00
I have 2 columns:
Duration | ID
0h 7m 55sec. | 1
0h 25m 33sec.| 2
10h 5m 5sec. | 3
4h 11m 31sec.| 4
Duration(nvarchar(255))
I want to calculate the Duration in TOTAL NUMBER OF SECONDS for each ID.
I tried using SUBSTRING and then CAST but it's not giving me the desired output. Any help on this would be much appreciated.
The query below is using str_to_date to cast the string, the time_to_sec function is converting the time portion to seconds.
This approach will break if duration exceeds 23h 59m 59sec. #Gordon Linoff's approach will handle that scenario.
select id,
duration,
time_to_sec(str_to_date(duration,'%Hh %im %ssec.')) as seconds_elapsed;
This answer is for MySQL, as the question was originally tagged.
Yuck. But you can do:
select (substring_index(col, 'h ', 1) * 60 * 60 +
substring_index(substring_index(col, 'm ', 2), ' ', -1) * 60 +
substring_index(substring_index(col, 'sec.',1),' ', -1)
) as duration_secs
from t;
This extracts each component and then uses implicit conversion for the calculation.
I have a query with the fields date hour and value.
It looks something like this
date hour value
xx/xx/xx 15 100
xx/xx/xx 30 122
xx/xx/xx 45 50
... 100 100
... 115 23
... ... ...
... ... ...
... 2400 400
... 15 23
Basically, date is the date, hour is the hour, and value is the value for that particular 15 minute interval. What I have been trying to figure out is a way to take each hour (so 15, 30, 45, and 100) or (1015, 1030, 1045, 1100) [As you can see hours are military-esque 1:00pm is 1300 and midnight 2400], and sum their values together. So i am looking to return something like this:
xx/xx/xx 100 372
xx/xx/xx 200 23 + (130 data) + (145 data) + (200 data)
And so on...
The table has on average around 100 days and they all start from 15 to 2400 incrementing by 15 with varying numbers for the value column.
I have thought about using a partition, group by, etc. with no real ideas how to tackle it. Essentially I have to take 4 rows (an hour), sum their values, spit out the date, hour, and summed value then repeat for every day. I am not asking for code, just some help with what i should be using since this seems like a simple problem minus the key to solving it.
Any help is greatly appreciated, Thank you!
Grouping by Hour/100 will almost get you there - subtract 1 from the hour will make 1 AM fall to 99, and get included in the grouping. This will give a query that looks like this:
SELECT Table1.Dte, Int(([tme]-1)/100) AS Hr, Sum(Table1.Val) AS TotVal
FROM Table1
GROUP BY Table1.Dte, Int(([tme]-1)/100);
I may have misremembered how you cast to int in Access, but this might work:
Select
[date],
100 * (1 + Cint(([Hour] - 1) / 100)),
Sum(Value)
From
Query
Group By
[date],
100 * (1 + Cint(([Hour] - 1) / 100))
Order By
1, 2
SELECT
DateCol,
Int(HourCol \ -100) * -100 AS Hr,
Sum(Value) AS Value
FROM
YourTable
GROUP BY
DateCol,
Int(HourCol \ -100) * -100
Or you can use ((Hr + 99) \ 100) * 100.