Calculate Sessions Between TimeRange in TSQL - tsql

Here is part of database:
SessionID SessionStartTime SessionCloseTime
24 2012-10-16 01:00:06.000 2012-10-16 01:01:22.000
24 2012-10-16 01:00:08.000 2012-10-16 01:01:10.000
24 2012-10-16 01:00:16.000 2012-10-16 01:01:12.000
24 2012-10-16 01:00:30.000 2012-10-16 01:01:48.000
24 2012-10-16 01:00:41.000 2012-10-16 01:02:08.000
24 2012-10-16 01:00:48.000 2012-10-16 01:01:34.000
24 2012-10-16 01:00:56.000 2012-10-16 01:03:09.000
24 2012-10-16 01:01:02.000 2012-10-16 01:02:13.000
24 2012-10-16 01:01:05.000 2012-10-16 01:03:16.000
24 2012-10-16 01:01:09.000 2012-10-16 01:02:42.000
24 2012-10-16 01:01:15.000 2012-10-16 01:02:48.000
24 2012-10-16 01:01:18.000 2012-10-16 01:02:14.000
24 2012-10-16 01:01:18.000 2012-10-16 01:02:06.000
24 2012-10-16 01:01:42.000 2012-10-16 01:03:16.000
24 2012-10-16 01:01:45.000 2012-10-16 01:03:04.000
I want to add a new column to this table named as SessionCount and then I will be able to see the call peaks I mean max count of sessions which happened at the same time.
This table should be like this:
SessionID SessionStartTime SessionCloseTime SessionCount
24 2012-10-16 01:00:06.000 2012-10-16 01:01:22.000 1
24 2012-10-16 01:00:08.000 2012-10-16 01:01:10.000 2
24 2012-10-16 01:00:16.000 2012-10-16 01:01:12.000 3
24 2012-10-16 01:00:30.000 2012-10-16 01:01:48.000 4
24 2012-10-16 01:00:41.000 2012-10-16 01:02:08.000 5
24 2012-10-16 01:00:48.000 2012-10-16 01:01:34.000 6
24 2012-10-16 01:00:56.000 2012-10-16 01:03:09.000 7
24 2012-10-16 01:01:02.000 2012-10-16 01:02:13.000 8
24 2012-10-16 01:01:05.000 2012-10-16 01:03:16.000 9
24 2012-10-16 01:01:09.000 2012-10-16 01:02:42.000 10
24 2012-10-16 01:01:15.000 2012-10-16 01:02:48.000 10
24 2012-10-16 01:01:18.000 2012-10-16 01:02:14.000 11
24 2012-10-16 01:01:18.000 2012-10-16 01:02:06.000 11
24 2012-10-16 01:01:42.000 2012-10-16 01:03:16.000 7
24 2012-10-16 01:01:45.000 2012-10-16 01:03:04.000 7
so in this table there are maximum 11 call peaks happened at the same time at 01:01:18. There are 11 active calls at 01:01:18. How can I calculate the sessions when session is active then +1 when session is finished then -1?

Expanding on the previous answer...
;with ids as
(
select *, ROW_NUMBER() over (order by sessionstarttime, sessionclosetime) rid from #t
),
cte as
(
select SessionStartTime as ChangeTime, 1 as CC, rid from ids
union all
select SessionCloseTime as ChangeTime, -1 as CC, rid from ids
)
select ids.id, ids.SessionStartTime,ids.SessionCloseTime, rt
from
ids
inner join
(
select cc,rid, changetime,rt from cte
cross apply
(select SUM(cc) as rt from cte c where c.changetime<=cte.changetime) rt
) res
on ids.rid=res.rid
where CC=1
order by SessionStartTime

Related

Postgres group by for last record from each month as array

I have a table with counter-values from different devices on different measuring applications.
I like to create a single view/selection for a year with the last counter values from every month per device and application.
The result should give the month timestamp and the associated value as an array.
In the example there is only on application id here
Table with counter values from different timestamps and devices
application_name
device_name
received_at
counter
0089
14200923
2022-06-08 18:02:43.663 +0200
29
0089
14200923
2022-06-09 16:14:42.933 +0200
36
0089
14200923
2022-06-10 16:14:42.696 +0200
60
0089
14200923
2022-06-22 16:14:25.496 +0200
188
0089
14200923
2022-07-12 16:14:02.207 +0200
314
0089
14200923
2022-07-13 16:14:00.709 +0200
348
0089
14200924
2022-06-07 10:58:34.962 +0200
13
0089
14200924
2022-06-07 13:22:34.884 +0200
13
0089
14200924
2022-06-22 17:10:21.613 +0200
258
0089
14200924
2022-07-01 17:10:16.740 +0200
296
0089
14200924
2022-07-12 17:10:06.566 +0200
440
Expected result: Last countervalue for device for each month as an json array
application_name
device_name
month_array
0089
14200923
[{"2022-06-22 16:14:25.496 +0200" : "188"},"2022-07-13 16:14:00.709 +0200" : "348"}]
0089
14200924
[{"2022-06-22 17:10:21.613 +0200" : "258"}, "2022-07-12 17:10:06.566 +0200" : "440"}]
I found and tried the rank solution from Stack26020770
and i can get the some single results but don't know how to combine this to have a single result as expected.
Using the Rank() function for every month and like to select only the row with rank=1.
select application_name,device_name,received_at,counter,
rank() over
(partition by DATE_TRUNC('month',received_at),DATE_TRUNC('year',received_at),
device_name order by received_at desc )
from device_up
order by application_name asc,device_name,received_at;
Get array result for a specific device.
select json_agg(row(received_at,counter))
from
( select application_name,received_at, counter,
rank() over (partition by DATE_TRUNC('month',received_at),
DATE_TRUNC('year',received_at) order by received_at desc) rk
from device_up where device_name='14200923'
) as sub where rk=1;
How to combine this in a sub query or with an group by ?
The fiddle link is here SQLFiddle

Past year sales value flag in tableau

I have a graph where I have sales value for Jan, Feb, Mar state wise. I want to mark a flag in a column, if sales exceeds previous month for March month say.
Sales Sales Sales
City1 Person 1 12 29 10
Person 2 14 15 19
Person 3 23 24 11
City2 Person 4 22 28 30
Person 5 14 15 10
Person 6 23 24 2
Jan Feb Mar and so on
So basically expected output would be:
Sales Sales Sales Flag
City1 Person 1 12 29 10 Down arrow
Person 2 14 15 19 Up arrow
Person 3 23 24 11 Down Arrow
City2 Person 4 22 28 30 Up arrow
Person 5 14 15 10 Down arrow
Person 6 23 24 2 Down arrow
Jan Feb Mar and so on
Can anyone tell how to do this in a graph visualisation?
The values of sales are sum (Sales) for Jan , Feb and Mar respectively for Cities corresponding to each person

get fetch the data of last 20 tuesday in aws redshift

I want to find data for the last 20 Tuesday.
I have to write fro getting the desired result as mentioned below.
Date value
2020-03-03 01:12:15 5
2020-02-25 07:12:15 13
2020-02-24 08:12:15 1
2020-02-23 09:12:15 32
2020-02-22 10:12:15 7
2020-02-21 11:12:15 43
2020-02-20 12:12:15 7
2020-02-19 13:12:15 1
2020-02-18 14:12:15 31
2020-02-17 15:12:15 14
2020-02-16 15:12:15 2
2020-02-15 15:12:15 14
2020-02-14 14:12:15 31
2020-02-13 15:12:15 11
2020-02-12 15:12:15 2
2020-02-11 15:12:15 14
2020-02-10 15:12:15 12
and so one
My desired output is
Date value
2020-02-24 01:12:15 1
2020-02-17 07:12:15 14
2020-02-10 14:12:15 12
and so on
You could probably use:
WHERE
DATE_PART(dow, date_field) = 2
AND date_field >= CURRENT_DATE - INTERVAL '140 DAYS'
See: DATE_PART Function - Amazon Redshift

IF function to determine if SYSDATE-1 or SYSDATE-3 should be used by determining Monday

I run this report Mon-Fri for the previous day's data and I am trying to figure out how to hard code TO_CHAR(TRUNC(SYSDATE-3) if today is
Monday (day the report is run) or use TO_CHAR(TRUNC(SYSDATE-1) for any other workday (mon - fri). I am assuming that this will require an IF, THEN, ELSE statement but am unsure of how to include that properly into my query.
SELECT
RRA.LAST_MODIFICATION_DATE AS "LAST MODIFICATION DATE",
TO_CHAR(TRUNC(SYSDATE-1),'DD-MON-RR') AS "DATA_DATE"
FROM PHOENIX.R_REFERRAL_ACTIVITY RRA
Where 1=1
AND RRA.LAST_MODIFICATION_DATE
BETWEEN TO_CHAR(TRUNC(SYSDATE-1),'DD-MON-RR') AND TO_CHAR(TRUNC(SYSDATE),'DD-MON-RR')
Aha; OK then, it seems that you'd need to use CASE along with TO_CHAR function which will tell you which day is "today". Have a look, see if it helps.
TEST is just a simple calendar, several days in this February. I'm removing Saturdays and Sundays (as you said you're interested in mon - fri only).
SQL> with test as
2 (select trunc(sysdate, 'mm') + level - 1 c_date,
3 to_char(trunc(sysdate, 'mm') + level - 1, 'dy') c_day
4 from dual
5 connect by level < 20
6 )
7 select
8 c_date todays_date,
9 c_day,
10 --
11 c_date - case when c_day = 'mon' then 3
12 else 1
13 end previous_work_date,
14 --
15 to_char(c_date - case when c_day = 'mon' then 3
16 else 1
17 end, 'dy') previous_work_day
18 from test
19 where c_day not in ('sat', 'sun')
20 order by 1;
TODAYS_DAT C_D PREVIOUS_W PRE
---------- --- ---------- ---
01.02.2018 thu 31.01.2018 wed
02.02.2018 fri 01.02.2018 thu
05.02.2018 mon 02.02.2018 fri
06.02.2018 tue 05.02.2018 mon
07.02.2018 wed 06.02.2018 tue
08.02.2018 thu 07.02.2018 wed
09.02.2018 fri 08.02.2018 thu
12.02.2018 mon 09.02.2018 fri
13.02.2018 tue 12.02.2018 mon
14.02.2018 wed 13.02.2018 tue
15.02.2018 thu 14.02.2018 wed
16.02.2018 fri 15.02.2018 thu
19.02.2018 mon 16.02.2018 fri
13 rows selected.
SQL>

Grouping Data TSQL

I'm trying to make a report which shows a users submitted forms.
I want each line to show one occurrence of each filed per user.
Username | First form submitted | Form address (1st form) | Last form submitted | Form Address (last form)
Here's what I have currently:
SELECT form.Name
,(SELECT COUNT (*) FROM dbo.vAdvF_155 af WHERE af.Name = form.Name) AS [TotalForms]
,(SELECT TOP 1 p.Timetag1 FROM dbo.vAdvF_155 af WHERE af.Name = form.Name ORDER BY [TimeTag1] ASC) AS [Started]
,(SELECT TOP 1 af.aField143 FROM dbo.vAdvF_155 af WHERE af.TimeTag1 = form.TimeTag1 ORDER BY [TimeTag1] DESC) AS [FirstFormAddress]
,(SELECT TOP 1 p.Timetag2 FROM dbo.vAdvF_155 af WHERE af.Name = form.Name ORDER BY [TimeTag2] DESC) AS [Submitted]
,(SELECT TOP 1 af.aField143 FROM dbo.vAdvF_155 af WHERE af.RecId = form.RecId ORDER BY [TimeTag2] DESC) AS [LastFormAddress]
FROM dbo.vAdvF_155 AS form INNER JOIN
dbo.PhoneData AS p ON form.RecId = p.RecID
ORDER BY form.Name
Results:
Name TotalForms Started FirstFormAddress Submitted LastFormAddress
CARL SUTTON 14 2016-07-22 09:30:55.000 19 Lilac Close KEYWORTH 2016-07-22 11:17:36.000 19 Lilac Close KEYWORTH
CARL SUTTON 14 2016-07-22 12:46:31.000 23 Lincoln Street NEWARK 2016-07-22 13:20:19.000 23 Lincoln Street NEWARK
CARL SUTTON 14 2016-07-25 10:24:52.000 104 Shireoaks COMMON 2016-07-25 12:04:59.000 104 Shireoaks COMMON
CARL SUTTON 14 2016-07-25 13:59:11.000 43 Milton DRIVE RAVENSHEAD 2016-07-25 15:53:28.000 43 Milton DRIVE RAVENSHEAD
CARL SUTTON 14 2016-07-26 10:22:53.000 17 LISMORE COURT MANSFIELD 2016-07-26 11:36:07.000 17 LISMORE COURT MANSFIELD
CARL SUTTON 14 2016-07-26 13:52:02.000 3 Ruby's AVENUE BALDERTON 2016-07-26 15:51:42.000 3 Ruby's AVENUE BALDERTON
CARL SUTTON 14 2016-07-27 09:35:54.000 The Elms Station Road NG14 7GD 2016-07-27 14:53:28.000 The Elms Station Road NG14 7GD
CARL SUTTON 14 2016-07-28 09:09:10.000 Main Road BULCOTE 2016-07-28 10:35:17.000 Main Road BULCOTE
CARL SUTTON 14 2016-07-28 12:04:17.000 NULL 2016-07-28 12:06:21.000 NULL
CARL SUTTON 14 2016-07-28 13:13:48.000 2 Midlands AVENUE STAPLEFORD 2016-07-28 15:14:32.000 2 Midlands AVENUE STAPLEFORD
CARL SUTTON 14 2016-07-31 08:14:03.000 Summit Close KIRKBY 2016-07-31 11:44:32.000 Summit Close KIRKBY
CARL SUTTON 14 2016-07-31 12:49:29.000 4 Archway Old Clipstone 2016-07-31 14:07:05.000 4 Archway Old Clipstone
CARL SUTTON 14 2016-08-01 08:20:21.000 5 RAVENSHEAD COURT 2016-08-01 10:08:39.000 5 RAVENSHEAD COURT
CARL SUTTON 14 2016-08-02 07:56:23.000 Field CLOSE GEDLING 2016-08-02 09:48:13.000 Field CLOSE GEDLING
CASEY MORTON 13 2016-07-22 09:12:08.000 10 ByRON CRESENT Ng162sx 2016-07-22 11:42:30.000 10 ByRON CRESENT Ng162sx
CASEY MORTON 13 2016-07-22 13:27:12.000 146 2016-07-22 16:05:29.000 146
CASEY MORTON 13 2016-07-25 09:14:37.000 5 Cossall Road NG93PG 2016-07-25 14:16:53.000 5 Cossall Road NG93PG
CASEY MORTON 13 2016-07-26 08:28:14.000 TenYSON Street NG74GA 2016-07-26 11:46:42.000 TenYSON Street NG74GA
CASEY MORTON 13 2016-07-26 14:31:17.000 NULL 2016-07-26 14:54:23.000 NULL
CASEY MORTON 13 2016-07-27 06:38:28.000 34 Sturton STREET Ng76hu 2016-07-27 09:24:37.000 34 Sturton STREET Ng76hu
CASEY MORTON 13 2016-07-27 09:59:05.000 12 TUDOR Close Ng42dr 2016-07-27 15:04:08.000 12 TUDOR Close Ng42dr
CASEY MORTON 13 2016-07-28 08:43:23.000 12 Ardmore Ng24gp 2016-07-28 11:27:35.000 12 Ardmore Ng24gp
CASEY MORTON 13 2016-07-28 11:48:28.000 9 Sycamore Close NG122DJ 2016-07-28 13:46:55.000 9 Sycamore Close NG122DJ
CASEY MORTON 13 2016-07-28 14:40:49.000 15 GoodLIFFE STREET Ng76fz 2016-07-28 15:54:07.000 15 GoodLIFFE STREET Ng76fz
CASEY MORTON 13 2016-08-01 09:50:08.000 24 VALESIDE Gardens NG42EP 2016-08-01 12:28:27.000 24 VALESIDE Gardens NG42EP
CASEY MORTON 13 2016-08-01 13:51:53.000 285 Derby Road Ng93ja 2016-08-01 16:09:11.000 285 Derby Road Ng93ja
CASEY MORTON 13 2016-08-02 07:21:38.000 Melrose House Raleigh Street Ng74hf 2016-08-02 11:24:27.000 Melrose House Raleigh Street Ng74hf
As you can see with the results it shows all the forms as they are not distinct, I literally just want it grouped into one line per person but can't figure the grouping.
Assuming a lot about the structure of your vAdvF_155 table/view, you may be able to get the results you are looking for with this:
declare #vAdvF_155 table (Name nvarchar(50)
,aField143 nvarchar(50)
,Timetag1 datetime
,Timetag2 datetime
)
insert into #vAdvF_155 values
('CARL SUTTON' ,'4 Archway Old Clipstone' ,'2016-07-31 12:49:29.000','2016-07-31 14:07:05.000')
,('CARL SUTTON' ,'5 RAVENSHEAD COURT' ,'2016-08-01 08:20:21.000','2016-08-01 10:08:39.000')
,('CARL SUTTON' ,'Field CLOSE GEDLING' ,'2016-08-02 07:56:23.000','2016-08-02 09:48:13.000')
,('CASEY MORTON','10 ByRON CRESENT Ng162sx' ,'2016-07-22 09:12:08.000','2016-07-22 11:42:30.000')
,('CASEY MORTON','146 Street Name' ,'2016-07-22 13:27:12.000','2016-07-22 16:05:29.000')
,('CASEY MORTON','5 Cossall Road NG93PG' ,'2016-07-25 09:14:37.000','2016-07-25 14:16:53.000')
select f.Name
,f.TotalForms
,f.FirstForm
,ff.aField143 as FirstFormAddress
,f.LastForm
,lf.aField143 as LastFormAddress
from (
select Name
,count(1) as TotalForms
,min(Timetag1) as FirstForm
,max(Timetag2) as LastForm
from #vAdvF_155
group By Name
) f
inner join #vAdvF_155 ff
on(f.Name = ff.Name
and f.FirstForm = ff.Timetag1
)
inner join #vAdvF_155 lf
on(f.Name = ff.Name
and f.LastForm = lf.Timetag2
)