SQL: how to group by dates in a row? [closed] - sql

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
It might be already answered before, but apparently I am not googling it right.
Let's say I have a table:
RecordingDate
2018-07-01
2018-07-02
2018-07-06
2018-07-09
2018-07-10
2018-07-11
2018-07-12
2018-07-16
2018-07-17
2018-07-18
I want to group the data by the date of the first recording and count days in a row with recordings:
DateOfFirstRecording RecordingsInARow
2018-07-01 2
2018-07-06 1
2018-07-09 4
2018-07-16 3
How do I do that ?

You can subtract an increasing sequence, to get a constant date. This is the idea:
select min(date), max(date), count(*)
from (select t.*, row_number() over (order by date) as seqnum
from t
) t
group by date - seqnum * interval '1 day'
order by min(date);
Date operations vary significantly depending on the database, but all databases support this functionality with some syntax.
EDIT:
In SQL Server, this looks like:
select
min(RecordingDate) as DateOfFirstRecording,
count(*) as RecordingsInARow
from (select Recordings.*, row_number() over (order by RecordingDate) as seqnum
from Recordings
) t
group by dateadd(day, - seqnum, RecordingDate)
order by min(RecordingDate);

Related

In Oracle, how to use SQL to solve this program? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I have a table
I want output like this:
This is a type of gaps-and-islands problem. You need to find the adjacent rows -- which you can do by subtracting a sequence. That is:
select t.*,
row_number() over (partition by trend, add_months(date, -seqnum) order by date) as new_trend
from (select t.*,
row_number() over (partition by trend order by day) as seqnum
from t
) t
You can use window functions as follows:
Select day, Row_number() over (partition by sm order by day) as trend
From
(Select t.*, Sum(case when trend = lg_trend then 0 else 1 end) over(order by day) as sm
From
(Select t.*, Lag(trend) over (order by day) as lg_trend
From yourtable t) t) t

How to get last (n) dates by sql query? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
For example DECLARE #a = 10;
Required output be like:
1) 16/5/2020
2) 15/5/2020
3) 14/5/2020
4) 13/5/2020
5) 12/5/2020
6) 11/5/2020
7) 10/5/2020
8) 9/5/2020
9) 8/5/2020
10) 7/5/2020
If Declare #b = 5 then get last five days of dates in output.
Snowflake:
SELECT DATEADD(DAY, -SEQ4(), CURRENT_DATE()) AS generated_date
FROM TABLE(GENERATOR(ROWCOUNT=>10))
ORDER BY generated_date desc;
SEQn() functions are not guaranteed to be gap free, so you need to use ROW_NUMBER()
WITH tally AS (
SELECT ROW_NUMBER() OVER(ORDER BY SEQ4()) AS rn
FROM TABLE(GENERATOR(ROWCOUNT=>10))
)
SELECT DATEADD(DAY, -rn, CURRENT_DATE()) AS generated_date
FROM tally
ORDER BY generated_date

how to get recent 6 dates (Max dates) [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I need recent 6 dates count
My code is
select DUE_DATE, count(*)
from DATA
group by DUE_DATE
03/24/2018 10
03/17/2018 20
03/10/2018 15
03/03/2018 23
02/24/2018 42
02/17/2018 32
02/10/2018 15
02/03/2018 17
01/27/2018 23
select DUE_DATE, count(*) from DATA group by DUE_DATE order by DUE_DATE desc limit 6
The simplest case would be if every date is presented and/or you're only interested in 6 most recent dates regardless of whether they're presented in your table or not:
select DUE_DATE, count(*)
from DATA
where DUE_DATE >= trunc(sysdate) - 5
group by DUE_DATE
order by DUE_DATE desc
(Note: dates that are not presented in your table won't be shown).
On the other hand, if you need 6 most recent dates from the subgroup of dates you have in your table, then you'll first need a subquery to fetch you those dates and than use count on those dates only:
select DUE_DATE, count(*)
from DATA
where DUE_DATE in (select distinct DUE_DATE
from DATA
order by DUE_DATE desc limit 6)
group by DUE_DATE
I hope I helped!
Are you looking for fetch first?
select DUE_DATE, count(*)
from DATA
group by DUE_DATE
order by DUE_DATE desc
fetch first 6 rows only;

how to ignore the day part of a date to group data [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I have the below query which works, however it seems very untidy and inefficient to me.
My table has two columns: TDate & Sales
TDate Sales
2016-03-25 5
2016-03-24 8
2016-03-28 7
2016-04-21 2
2016-04-14 1
I want to group the data by year and month, i.e. i don't care about the day part of the date. The result (which the query below does give) is,
TDate Sales
201603 20
201604 3
What is the best way to achieve this?
select left(convert(nvarchar, TDate, 112),6), sum(Sales)
from mytbl
group by left(convert(nvarchar, TDate, 112),6)
order by left(convert(nvarchar, TDate, 112),6)
convert the dates to first day(any static day) of month and do the grouping
Here is one way using EOMONTH
select dateadd(dd,1,eomonth(TDate,-1)) as Tdate,sum(sales)
from mytbl
Group by dateadd(dd,1,eomonth(TDate,-1))
Order by Tdate
or use DATEFROMPARTS
select DATEFROMPARTS(year(TDate),month(TDate),1)) as Tdate,sum(sales)
from mytbl
Group by DATEFROMPARTS(year(TDate),month(TDate),1))
Order by Tdate
This will make sure the dates are properly ordered. In your approach the dates are ordered as string. Both approaches work on Sql Server 2012 and above
For older versions
select DATEADD(mm, DATEDIFF(mm,0,TDate), 0) as Tdate,sum(sales)
from mytbl
Group by DATEADD(mm, DATEDIFF(mm,0,TDate), 0)
Order by Tdate
For me your query is OK but, maybe use of DATEPART instead of string conversion can be result more efficient as time spent.
Try this:
select DATEPART(year, TDate) *100 + DATEPART(month, TDate), sum(Sales)
from mytbl
group by DATEPART(year, TDate) *100 + DATEPART(month, TDate)
order by DATEPART(year, TDate) *100 + DATEPART(month, TDate)
Wrap your original query up in a derived table to save some typing, and also make it ANSI SQL compliant:
select TDate, sum(Sales)
from
(
select left(convert(nvarchar, TDate, 112),6) TDate, Sales
from mytbl
) dt
group by TDate
order by TDate
This way you don't have to write the same expression three times! (I.e. easier to adjust/maintain.)
(Same trick can be used for the other answers to the question.)

Calculating balance Oracle [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I've got a problem. I just wanna calc the balance of my table.
my select statement is:
select date, ammount, ?? as Balance
from table
where accountnr = 123
order by date
Output should look like this:
Date Ammount Balance
07/02/2016 -145.55 945.65
25/01/2016 349.45 1091.20
11/11/2015 340.25 741.75
30/09/2015 369.10 401.50
05/04/2015 32.40 32.40
I tried so long, with different ways without luck.
You can do it in a single table scan (i.e. without any joins or correlated sub-queries) with an analytical query:
SELECT "date",
amount,
SUM( amount ) OVER ( ORDER BY "date" ) AS balance
FROM your_table;
If there are multiple accounts in the table then:
SELECT account_number,
"date",
amount,
SUM( amount ) OVER ( PARTITION BY account_number ORDER BY "date" ) AS balance
FROM your_table;