Creating a table using hourly readings from a current table - sql

I have a table that is being used to log values every second
datetime float float
25/02/2013 08:18:56 6 147
I need to create a table that has a single row for each hour over the last month.
Any help appreciated.

Why not just query the table for what you want?
The following query will return the first reading in every hour:
select <columns you want here>
from (select t.*,
row_number() over (partition by year(datetime), month(datetime), day(datetime),
datepart(hour, datetime)
) as seqnum
from t
) t
where seqnum = 1
You can put this into a table, adding the into statement after the select.

Related

SQL Group by balance

I have a table like below:
I want the results to be like below which fetch the start and end of the balance but we can't use group by as balance should be grouped only based on consecutive groups. can you please help me with this ?:
There is most certainly a duplicate of this question, however, it is easier to crank out an answer than to search. These types of problems, data in the order inserted or shown with no order indicator, can simply be solved by two derivative queries. The first to use LAG or LEAD to check for gaps and the second to sum up the changes which are represented by a value of 1 as opposed to 0. The key here, using MSSQL Server, is SUM(x) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING).
DECLARE #T TABLE(balance INT, date DATETIME)
INSERT #T VALUES
(36,'1/1/2020'),
(36,'1/2/2020'),
(36,'1/3/2020'),
(24,'1/4/2020'),
(24,'1/5/2020'),
(36,'1/6/2020'),
(36,'1/7/2020'),
(37,'1/8/2020'),
(38,'1/9/2020')
;WITH GapsMarked AS
(
--If the prev value by date (by natural order of data above) does not equal this value mark it as a boundry
SELECT *,
IsBoundry = CASE WHEN ISNULL(LAG(balance) OVER (ORDER BY date),balance) = balance THEN 0 ELSE 1 END
FROM #T
)
,VirtualGroup AS
(
SELECT
*,
--This serialzes the marked groups into seequntial clusters
IslandsMarked = SUM(IsBoundry) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING)
FROM
GapsMarked
)
SELECT
MAX(balance) AS balance,
MIN(date) AS start,
MAX(date) AS [end]
FROM
VirtualGroup
GROUP BY
IslandsMarked
select balance, min(start), max(end) from table where balance is in (
select balance from table
group by balance)
Hope it will help you

How to get the latest 3 records of each group from dolphindb database?

My table name is trades, and its columns are permno, symbol, date, prc, shrout, ret, vol. I want to get the latest 3 records of each stock each date group. Does DolphinDB support such querying methods?
declare #trades as table
(
permno int,
symbol int,
groupdate date
)
insert into #trades(permno,symbol,groupdate)
values
(1,1,'2019-01-01'),
(2,2,'2019-01-01'),
(3,3,'2019-01-01'),
(4,4,'2019-01-01'),
(1,11,'2019-01-02'),
(2,22,'2019-01-02'),
(3,33,'2019-01-02'),
(4,44,'2019-01-02')
select * from(
select ROW_NUMBER() over(partition by groupdate order by groupdate)as rn,* from #trades)x
where rn <=3
In DolphinDB, one can use context-by clause to solve similar problems. For your question, use the code below:
select * from trades context by symbol, date limit -3
A negative value -3 for limit clause tells the system to get last 3 records for each symbol and date combination.

How to calculate difference between current date and previous date in different rows

Hi I want to calculate the difference between dates in different rows using sql teradata assistant
my table look like this
create table test (
id INT,
Dx varchar(10)
Dx_date date);
insert into TEST values(1,'E14','2015-05-03');
insert into TEST values(1,'E15','2013-05-06');
insert into TEST values(1,'E15','2016-03-03');
insert into TEST values(2,'E15','2012-03-04');
insert into TEST values (3,'E144','2011-03-04');
insert into TEST values (3,'E122','2011-02-04');
Than to calculate the difference of dates between each row I'm using this code
select id,
dx,
Date_dx,
zeroifnull (MDIFF(Date_dx,1,id,dx)
from TEST
group by id;
But it gaves me wrong results
Thank you for the help
A window function should make this easy.
For date difference in days:
Select *
,DateDiff(DD, Dx_date, Lag(Dx_Date) Over (Order By Dx_date)) DateDiff
From test
Although you did not specify, your attempt to calculate the date, suggests you many be interested in calculating dates per id, so;
Select *
,DateDiff(DD, Dx_date, Lag(Dx_Date) Over (Partition by id Order By Dx_date)) DateDiff
From test
Note: you may need to edit the date function as appropriate.
Try this:
select id, dx, datediff(day, lastdate, date_dx) datedifference from (
select id,
dx,
Date_dx,
lag(Date_dx,1,null) over(order by id)lastdate
from TEST)A
I found the solution
select id ,dx,Dx_date,
zeroifnull(dx_date-min(dx_date) over (partition by id order by dx_date rows
between 1 preceding and 1 preceding )) as difference _dx_date
from TEST;
Thank you

How to select row with group into 2 specific values by Descending order?

I would like to select queries a table with group by only 2 value in specific field. Like example bellow.
I have a table that normally having 2 value each minute. But some time having more than 2 value in each minute and I have selected by descending order.
Avoid that, I want to field of minute value [TimeStamp] can be group by 2 item based descending order and skip when have more than 2 value.
SELECT TOP 10
dbo.ConRadVacuum.[TimeStamp],
dbo.ConRadVacuum.Tag,
dbo.ConRadVacuum.[Value]
FROM
ConRadVacuum
ORDER BY
[TimeStamp] DESC
I want "selected row" (32 minute) can be selected only two like the other rows
I think you can use row_number() function by partitioning over minute part of your timestamp field, something like this:
select *
from (
select *,
row_number() over (
partition by datepart(minute, cast([TimeStamp] as datetime))
--^^ I use `datepart()` over cast of your timestamp field
--If your field is `datetime` you don't need to `cast`
order by [TimeStamp] desc) seq
from t) tt
where seq <= 2;
SQL Fiddle Demo
I didn't get your question very well, but i think you can put your query in CTE and add ROW_Number to it, then select your cte where your row number field is 1 or 2

Add ID column to a query result

This is my first time asking a question about T-SQL and I am a beginner with it. I have a SQL query which consists of two CTE's filtered down to less than 10 rows. I am using a SUM statement to get a running total:
Sum(Diff) OVER(ORDER BY DateAdded) AS Summary
DateAdded has the same value for several rows. Therefore, it does not give me a running total for each row. I need to create a field that simply counts the number of rows (similar to a PK in a DB table) so I can use it for my ORDER BY clause. If my understanding is correct, this is what I need to do to make it work. How can I add an enumerated column to the query result set? Please note, I do not want to ALTER a table, just add a column to the query result. I hope what I wrote is clear. Thank you!
Instead of using count() or sum() you can use row_number() which will give a distinct row number, starting at 1, for each row in your result set:
SELECT ROW_NUMBER() OVER (ORDER BY dateAdded) as Summary
Try this:
DECLARE #Result TABLE
(
DT DATETIME
)
INSERT INTO #Result SELECT '1 Jan 1900'
INSERT INTO #Result SELECT '1 Jan 1900'
SELECT ROW_NUMBER() OVER(ORDER BY DT DESC) AS "Row Number", DT
FROM #Result
I believe that you can just add NEWID() to your ORDER BY:
SELECT SUM(diff) OVER (ORDER BY DateAdded, NEWID()) AS Summary