Get the timestamp of max value in TDengine - sql

I'm trying to downsample with interval in TDengine.
I have a statement:
select _wstart, max(val) max_val, min(val) min_val from d1001 interval(5s);
enter image description here
You can see in the picture, and it is ok.
Now I want to get the timestamp for max/min value, how should I change the sql statement?

First of all, it needs to be understood that the timestamps of the maximum and minimum values are different. So they need to be obtained separately.
You can try:
select ts, max(val) max_val from d1001 interval(5s);
or
select ts, max(val) max_val from d1001 interval(5s);

Related

sql server lag function where condition

In the database, I have +1000,+2000,+3000..... increasing values according to the previous value. These sometimes do not increase, but decrease, I wrote a listing query to find this out.
select NUMBER-lag(NUMBER) over (ORDER BY DATE_TIME) AS 'DIFF'
from exampleTable with(nolock)
WHERE CONDITION1='abcdef' AND DATE_TIME >='20220801'
This works and I export to excel and filter and find the ones less than 0, but should I add them directly to the where part in sql?
I tried HAVING because it is a non-normal field, and it didn't work either.
AND (NUMBER-lag(NUMBER) over (ORDER BY DATE_TIME))<0
ORDER BY DATE_TIME ASC
So basically it is like this,
;WITH CTE AS (
select NUMBER-lag(NUMBER) over (ORDER BY DATE_TIME) AS'DIFF' from exampleTable with(nolock)
WHERE CONDITION1='abcdef' AND DATE_TIME >='20220801'
)
SELECT * FROM CTE WHERE DIFF <0

How to get the the value based on range?

Event
Range
value
A
0-30
20
A
30-80
70
A
80-100
10
output : A falls under 30-80 Range
We can use the SPLIT() function here along with a cast to integer, on both ends of each range:
SELECT *
FROM yourTable
WHERE value BETWEEN CAST(SPLIT("Range", '-')[offset(0)] AS int64) AND
CAST(SPLIT("Range", '-')[offset(1)] AS int64);
You can use Array_AGG to get the values and use offset. For your requirement, you can try below BigQuery query:
Query :
SELECT AS VALUE ARRAY_AGG(t ORDER BY value DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.table` t
GROUP BY event
Output :
Consider below approach
select * from your_table
qualify 1 = row_number() over(partition by event order by value desc)
if applied to sample data in your question - output is

SQLite averaging lot of rows into X averaged value between two desired row

I have rows in SQLite, let's say 10.0000 with last row as unix timestamp. I would like to average every value from today 00:00 to 23:59 into X averaged group. If there is 1000 records today and X is 10, then average each 100 value and the result would be 10x averaged 100 records. If x is 20, average each value and result is averaged values 50x. Those values are from sensors, like temperature and I would like to be able to track what the temperature was today between X and Y hours and so, for each day.
What would be the best efficient way to do this? I'm using SQLite3 with C++, I could do it in C++ with more queries but I would like to let this to SQLite and fetch the result only if it's possible. Visualization: https://i.ibb.co/grSTgrZ/sqlite.png
Any help appreciated where I should start with this.
Thanks.
You can use NTILE() window function to create the groups on which you will aggregate:
SELECT AVG(value) avg_value
FROM (
SELECT *, NTILE(3) OVER (ORDER BY id) grp
FROM tablename
)
GROUP BY grp
The number inside the parentheses of NTILE() corresponds to the number X in your requirement.
Id is the column on which the table should be ordered.
If you have a date column then change to:
SELECT AVG(value) avg_value
FROM (
SELECT *, NTILE(3) OVER (ORDER BY date) grp
FROM tablename
)
GROUP BY grp
See a simplified demo.

ROW_NUMBER() doesnt count right on timestamp

I always thought ROW_NUMBER() counts every row +1, but with my timestamp data it doesnt work.
ID TIME
1 2017-05-29 21:08:51.393401
1 2017-05-29 21:08:51.393401
1 2017-01-03 09:37:31.30511
1 2017-01-03 09:37:31.30511
...
WITH CTE AS( select ID,TIME, ROW_NUMER() OVER (PARTITION BY ID ORDER
BY TIME) AS TEST from XY )
RESULT
ID TIME TEST
1 2017-05-29 21:08:51.393401 1
1 2017-05-29 21:08:51.393401 1
1 2017-01-03 09:37:31.30511 2
1 2017-01-03 09:37:31.30511 2
...
The desired result should be 1, 2, 3, 4 and so on...
Edit: to solve the problem, select distinct.
But perhaps someone can reproduce the fact on a Netezza and confirm, that it´s not working as it should.
This looks like a bug in Netezza. The result you are getting looks like DENSE_RANK rather than ROW_NUMBER.
You should be able to circumvent the bug by extending the ORDER BY clause with a random number, so the DBMS picks one row arbirarily on a tie on time, as it is supposed to do.
WITH CTE AS
(
SELECT id, time, ROW_NUMER() OVER (PARTITION BY id ORDER BY time, RANDOM()) AS TEST
FROM xy
)
SELECT * FROM cte
ORDER BY id, test;
try like below by removing partition by id
WITH CTE AS (
select ID,TIME, ROW_NUMER() OVER (ORDER BY TIME) AS TEST from XY
) select * from cte
I find it hard to believe that this is a bug in Netezza. That is possible, but I would first explore whether the ids are really the same.
For instance, if id is a string and ends in a space, then this will return "1":
with t as (
select '1' as x union all
select '1 '
)
select *, row_number() over (partition by x order by x)
from t;
There are other reasons why values might look the same.
If id is an integer (or numeric), then what-you-see-is-what-you-get, so that would suggest a bug.
I found the solution for this issue, Add Partition on time by converting it to varchar datatype, try below
WITH CTE AS( select ID,TIME, ROW_NUMER() OVER (PARTITION BY ID, TO_VARCHAR(TIME) ORDER
BY TIME) AS TEST from XY ) e,

Is there a way to check LEAD() function's value for NULL in PostgreSQL

I need to check for NULL the value returned by LEAD() function.
SELECT LEAD(created_at) OVER (order by id, created_at) - created as diff
Normally, the NULL value is for the last row in the group. In this case, you can just use the 3-argument form of LEAD():
SELECT (LEAD(created_at, 1, <replacement value>) OVER (order by id, created_at) -
created_at
) as diff
Note that this only replaces NULL values that are the last values in the group. If there are NULL values in the data, you will actually get NULL. This is normally the behavior that you want.
Suitable solution:
SELECT coalesce(LEAD(created_at) OVER (order by id, created_at), now()) - created as diff
Thank's