I have a SQL view that produces the following list of Mondays in a specific date range as shown below:
Date Number
16/12/2013 208
23/12/2013 190
30/12/2013 187
15/12/2014 203
22/12/2014 190
29/12/2014 153
14/12/2015 225
21/12/2015 217
28/12/2015 223
Is it possible to order them by the first of each year then the second then the third etc. to give me the results as shown below:
Date Number
16/12/2013 208
15/12/2014 203
14/12/2015 225
23/12/2013 190
22/12/2014 190
21/12/2015 217
30/12/2013 187
29/12/2014 153
28/12/2015 223
Thank you in advance for any help or advice.
I think you should be able to get what you want by using the row_number() over a partition on the year, for example:
Select [Date], [Number],
Row_Number() over (PARTITION BY Year([DATE] order by [DATE]) as WEEK_IN_YR
from [table]
order by WEEK_IN_YR, [Date]
https://msdn.microsoft.com/en-gb/library/ms186734.aspx
Related
I have a query:
SELECT
date,
COUNT(o.row_number)FILTER (WHERE o.row_number > 1 AND date_ddr IS NOT NULL AND telephone_number <> 'Anonymous' ) repeat_calls_24h
(
SELECT
telephone_number,
date_ddr,
ROW_NUMBER() OVER(PARTITION BY ddr.telephone_number ORDER BY ddr.date) row_number,
FROM
table_a
)o
GROUP BY 1
Generating the following table:
date
Repeat calls_24h
17/09/2022
182
18/09/2022
381
19/09/2022
81
20/09/2022
24
21/09/2022
91
22/09/2022
110
23/09/2022
231
What can I add to my query to provide a sum of the previous three days as below?:
date
Repeat calls_24h
Repeat Calls 3d
17/09/2022
182
18/09/2022
381
19/09/2022
81
644
20/09/2022
24
486
21/09/2022
91
196
22/09/2022
110
225
23/09/2022
231
432
Thanks
We can do it using lag.
select "date"
,"Repeat calls_24h"
,"Repeat calls_24h" + lag("Repeat calls_24h") over(order by "date") + lag("Repeat calls_24h", 2) over(order by "date") as "Repeat Calls 3d"
from t
date
Repeat calls_24h
Repeat Calls 3d
2022-09-17
182
null
2022-09-18
381
null
2022-09-19
81
644
2022-09-20
24
486
2022-09-21
91
196
2022-09-22
110
225
2022-09-23
231
432
Fiddle
I was trying to solve the "analyze weather patterns" problem as described here (https://joins-238123.netlify.com/window-functions/)
You're worried that hurricanes are happening more frequently, so you
decide to do a tiny bit of analysis. For each kind of weather event
find the 2 events that occurred the closest together and when they
happened
Table weather with data like:
type day
rain 6
rain 12
thunderstorm 13
rain 21
rain 27
rain 37
rain 44
rain 54
thunderstorm 56
rain 58
rain 61
rain 65
rain 68
rain 73
rain 82
hurricane 87
rain 92
rain 95
rain 98
rain 108
thunderstorm 111
rain 118
rain 123
rain 128
rain 131
hurricane 135
rain 136
rain 140
rain 149
thunderstorm 158
rain 159
rain 167
rain 175
hurricane 178
rain 179
rain 186
rain 192
rain 200
thunderstorm 202
rain 210
rain 219
thunderstorm 222
rain 226
rain 232
thunderstorm 238
rain 241
rain 246
rain 253
thunderstorm 257
rain 257
rain 267
rain 277
rain 286
rain 295
rain 302
rain 307
thunderstorm 312
rain 316
rain 325
thunderstorm 330
I could come up with :
select type, day, COALESCE(day - LAG(day, 1) over (partition by type order by day), 0) as days_since_previous from weather
It gives me results like:
type day days_since_previous
hurricane 87 0
hurricane 135 48
hurricane 178 43
rain 6 0
rain 12 6
rain 21 9
rain 27 6
But I can't get it to narrow the results down to the 2 closest events and only display the days between them.
How do I go about doing so that I get the desired result like:
type day days_since_previous
rain 61 3
hurricane 178 43
thunderstorm 238 16
You can use another window function to widdle down the rows:
SELECT type, day, days_since_previous
FROM (
SELECT type, day, (day - prev_day) AS days_since_previous,
ROW_NUMBER() OVER(PARTITION BY type ORDER BY (day - prev_day)) AS RowNum
FROM (
select type, day,
LAG(day, 1) over (partition by type order by day) as prev_day
from weather
) src
WHERE prev_day IS NOT NULL -- Ignore "first" events
) src
WHERE RowNum = 1
order by day
I also removed the COALESCE since that was causing the "first" events to be included in the calculations.
If you don't insist on displaying the day value - you could run a nested query:
In one SELECT (in a WITH clause, or a nested sub-select) add the gap to previous day as an OLAP function, as you suggest. No need to COALESCE, really ..
From that fullselect , run a GROUP BY select.
Like so:
WITH
w_gap2prev AS (
SELECT
*
, day - LAG(day) OVER(PARTITION BY type ORDER BY day) AS gap
FROM input
)
SELECT
type
, MIN(gap) AS days_since_previous
FROM w_gap2prev
WHERE gap IS NOT NULL
GROUP BY type
;
-- out type | days_since_previous
-- out --------------+---------------------
-- out hurricane | 43
-- out rain | 3
-- out thunderstorm | 16
-- out (3 rows)
-- out
-- out Time: First fetch (3 rows): 56.441 ms. All rows formatted: 56.479 ms
I need help to solve this.
Hopefully someone can giving me advices.
For a sample, I've got data like :
PROCLIB.MARCH 1
First 10 Rows Only
Flight Date Depart Orig Dest Miles Boarded Capacity
-----------------------------------------------------------------
114 01MAR94 7:10 LGA LAX 2475 172 210
202 01MAR94 10:43 LGA ORD 740 151 210
219 01MAR94 9:31 LGA LON 3442 198 250
622 01MAR94 12:19 LGA FRA 3857 207 250
132 01MAR94 15:35 LGA YYZ 366 115 178
271 01MAR94 13:17 LGA PAR 3635 138 250
302 01MAR94 20:22 LGA WAS 229 105 180
114 02MAR94 7:10 LGA LAX 2475 119 210
202 02MAR94 10:43 LGA ORD 740 120 210
219 02MAR94 9:31 LGA LON 3442 147 250
and i have condition for ('LAX,ORD'), 'LAX','LON','YYZ',('PAR,LON,FRA'),'FRA' ...AND ELSE
What should i do with that data to show report as that condition in SQL?
Parameter that I made is
Dest like #dest -> (from table condition(('LAX, ORD'), 'LAX','LON',('PAR,LON,FRA'),'FRA',..etc)) +'%'
And Date like #date + '%'
And Depart like #depart + '%'
If I choose 'LAX' as #dest, then only 'LAX' will show
If I choose 'LAX,ORD' as #dest, then only 'LAX' and 'ORD' will show
Please I need help, advice and suggestion for this.
Thanks
If your #dest value is 'LAX,ORD', one query that will solve your solution is
select *
from PROCLIB.MARCH
where dest in ('LAX','ORD')
To parameterise that, you need it to become a table.
Dest
====
LAX
ORD
and the query becomes
select *
from PROCLIB.MARCH
where dest in (select Dest from #DestTable)
If you want to pass #dest as a string parameter, then you need to split it somehow into a table. A search for SQL split function will give a number of options.
If your query is encapsulated in a stored procedure, a better method is to pass the values as a table valued parameter. See http://blog.sqlauthority.com/2008/08/31/sql-server-table-valued-parameters-in-sql-server-2008/
I have data like this.
Process_date SEQ_No
------------- ---------
16-MAR-13 733
09-MAR-13 732
02-MAR-13 731
24-FEB-13 730
16-FEB-13 728
09-FEB-13 727
02-FEB-13 726
26-JAN-13 725
21-JAN-13 724
12-JAN-13 723
05-JAN-13 722
29-DEC-12 721
24-DEC-12 720
15-DEC-12 719
08-DEC-12 718
03-DEC-12 717
22-NOV-12 716
17-NOV-12 715
10-NOV-12 714
03-NOV-12 713
29-OCT-12 712
23-OCT-12 711
13-OCT-12 710
05-OCT-12 709
28-SEP-12 708
22-SEP-12 707
15-SEP-12 706
08-SEP-12 705
01-SEP-12 704
Every month admin will refresh actual data table and automatically this above table will update with unique seq_no and process_date.
I need to extarct min date of everymonth(First refresh of last 6 months - excluding currrent month) and also seq_no related to that month so using joins(using seq_no - that is available in main table) i can combine actual data.
I need result like:
02-MAR-13 731 ( I don't need MAR as it should not take current month data)
so i need final result like below:
02-FEB-13 726
05-JAN-13 722
08-DEC-12 718
03-NOV-12 713
05-OCT-12 709
01-SEP-12 704
--sorry for asking direct quetion like this. I am not sure how to do that. thats the reason i have not prepared/posted any query.
select Process_date, SEQ_No
from (select Process_date, SEQ_No,
row_number() over (partition by trunc(process_date, 'mm') order by process_date) rn
from yourtab
where Process_date < trunc(sysdate, 'mm'))
where rn = 1;
will do that
fiddle example: http://sqlfiddle.com/#!4/a5452/1
I didn't understood how seq_no is in another table...
But using the input data:
select
min(process_date),
min(seq_no) keep (dense_rank first order by process_date)
from
your_table
where
process_date between add_months(trunc(sysdate,'MM'),-7)
and last_day(add_months(sysdate, -1))
group by
trunc(process_date,'MM');
Try:
SELECT seq_no,process_date FROM my_table
WHERE process_date IN (SELECT min(process_date)
FROM my_table
GROUP BY TRUNC(process_date,'MM'))
May I ask for your help with the following please ?
I am trying to calculate a change from one record to the next in my results. It will probably help if I show you my current query and results ...
SELECT A.AuditDate, COUNT(A.NickName) as [TAccounts],
SUM(IIF((A.CurrGBP > 100 OR A.CurrUSD > 100), 1, 0)) as [Funded]
FROM Audits A
GROUP BY A.AuditDate;
The query gives me these results ...
AuditDate D/M/Y TAccounts Funded
--------------------------------------------
30/12/2011 506 285
04/01/2012 514 287
05/01/2012 514 288
06/01/2012 516 288
09/01/2012 520 289
10/01/2012 522 289
11/01/2012 523 290
12/01/2012 524 290
13/01/2012 526 291
17/01/2012 531 292
18/01/2012 532 292
19/01/2012 533 293
20/01/2012 537 295
Ideally, the results I would like to get, would be similar to the following ...
AuditDate D/M/Y TAccounts TChange Funded FChange
------------------------------------------------------------------------
30/12/2011 506 0 285 0
04/01/2012 514 8 287 2
05/01/2012 514 0 288 1
06/01/2012 516 2 288 0
09/01/2012 520 4 289 1
10/01/2012 522 2 289 0
11/01/2012 523 1 290 1
12/01/2012 524 1 290 0
13/01/2012 526 2 291 1
17/01/2012 531 5 292 1
18/01/2012 532 1 292 0
19/01/2012 533 1 293 1
20/01/2012 537 4 295 2
Looking at the row for '17/01/2012', 'TChange' has a value of 5 as the 'TAccounts' has increased from previous 526 to 531. And the 'FChange' would be based on the 'Funded' field. I guess something to be aware of is the fact that the previous row to this example, is dated '13/01/2012'. What I mean is, there are some days where I have no data (for example over weekends).
I think I need to use a SubQuery but I am really struggling to figure out where to start. Could you show me how to get the results I need please ?
I am using MS Access 2010
Many thanks for your time.
Johnny.
Here is one approach you could try...
SELECT B.AuditDate,B.TAccounts,
B.TAccount -
(SELECT Count(NickName) FROM Audits WHERE AuditDate=B.PrevAuditDate) as TChange,
B.Funded -
(SELECT Count(*) FROM Audits WHERE AuditDate=B.PrevAuditDate AND (CurrGBP > 100 OR CurrUSD > 100)) as FChange
FROM (
SELECT A.AuditDate,
(SELECT Count(NickName) FROM Audits WHERE AuditDate=A.AuditDate) as TAccounts,
(SELECT Count(*) FROM Audits WHERE (CurrGBP > 100 OR CurrUSD > 100)) as Funded,
(SELECT Max(AuditDate) FROM Audits WHERE AuditDate<A.AuditDate) as PrevAuditDate
FROM
(SELECT DISTINCT AuditDate FROM Audits) AS A) AS B
Instead of using a Group By I've used subquerys to get both TAccounts and Funded, as well as the Previous Audit Date, which is then used on the main SELECT statement to get TAccounts and Funded again but this time for the previous date, so that any required calculation can be done against them.
But I would imagine this may be slow to process
It's a shame MS never made this type of thing simple in Access, how many rows are you working with on your report?
If it's under 65K then I would suggest dumping the data on to an Excel spreadsheet and using a simple formula to calculate the different between rows.
You can try something like the following (sql is untested and will require some changes)
SELECT
A.AuditDate,
A.TAccounts,
A.TAccounts - B.TAccounts AS TChange,
A.Funded,
A.Funded - B.Funded AS FChange
FROM
( SELECT
ROW_NUMBER() OVER (ORDER BY AuditDate DESC) AS ROW,
AuditDate,
COUNT(NickName) as [TAccounts],
SUM(IIF((CurrGBP > 100 OR CurrUSD > 100), 1, 0)) as [Funded]
FROM Audits
GROUP BY AuditDate
) A
INNER JOIN
( SELECT
ROW_NUMBER() OVER (ORDER BY AuditDate DESC) AS ROW,
AuditDate,
COUNT(NickName) as [TAccounts],
SUM(IIF((CurrGBP > 100 OR CurrUSD > 100), 1, 0)) as [Funded]
FROM Audits
GROUP BY AuditDate
) B ON B.ROW = A.ROW + 1