Oracle SQL group by week /month - oracle

How can we group reocrds weekly/monthly in oracle between from date and to date so that one record can be returned for one week/month.
e.g If we have 5 records for Ist weeek and 3 records for second week between a from date and to date then it should return total 2 records(one for Ist week and one for second week).
Thanks in advance.

You can group the results using GROUP BY: http://www.techonthenet.com/oracle/group_by.php
To select only those between from date and to date use WHERE
EDIT
For selecting the begining of the week or month, you can use TRUNC(the_date_field, ): http://www.techonthenet.com/oracle/functions/trunc_date.php
For example this groups by week:
SELECT TRUNC(datecol_name, 'WW') FROM table_name GROUP BY TRUNC(datecol_name, 'WW');

Related

I need to filter an Oracle SQL query on persons who turned age 21 during the calendar year of 2019

I need to filter an Oracle SQL query on persons who turned age 13 during the calendar year of 2019 - in other words, persons who had their 13th birthday sometime in 2019. Anyone know the code for that? Thanks in advance.
Assuming your table has a date_of_birth column this would work (2006 being 2019-13):
select *
from your_table
where to_number(extract(year from date_of_birth)) = 2006;
I notice your question title has a different year value from its body, so perhaps we need to hand over the troublesome maths to SQL:
select *
from your_table
where date '2019-01-01' = trunc(date_of_birth, 'yyyy') + interval '21' year
/
Truncating the DOB with a format mask converts all the dates to the first of January for that year. We then add an interval of 21 years. Comparing that value to the first of January 2019 will give you everybody who turned 21 last year.
I would use between clause with date_of_birth + 21 year to let oracle use index on date_of_birth, if any as following:
select *
from your_table
where date_of_birth + interval '21' year between date '2019-01-01' and date '2019-12-31';
Cheers!!

Why does my total session (aggregated using EXTRACT MONTH) is less than total session if I broke down by the date?

I'm trying to generate my total session by month. I've tried using two different ways.
I'm using date field for the first column
I'm using month field that is extracted from date field using EXTRACT(MONTH FROM date) AS month
I have tried using below code for the 1st one:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT date_key, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the 2nd one I tried using this code:
with
session1 as(
select date,
session_id
from table
where date >= '2019-05-20' AND date <= '2019-05-21')
SELECT EXTRACT (MONTH FROM date_key) AS month, COUNT(DISTINCT session_id) AS sessions from session1
GROUP BY 1
For the result, I got the output as per below:
20 May: 1,548 Sessions; 21 May: 1,471 Sessions; Total: 3,019
May: 2,905
So, there's 114 session discrepancy and I'd like to know why.
Thank you in advance.
For simplicity sake - let's say there is only one session during two consecutive days. So if you will count by day and then sum result - you will get 2 sessions, while if you will count distinct sessions for whole two days - you will get just 1 session
Hope this shows you the reason why - you are counting some sessions twice on different days - maybe when they go over end of one and start of next day
The following query should show you which sessions_ids occur on both dates.
select session_id, count(distinct date) as num_dates
from table
where date >= '2019-05-20' AND date <= '2019-05-21'
group by 1
having num_dates > 1
This is either a data processing issue, or your session definition is allowed to span multiple days. Google Analytics, for example, traditionally ends a session and begins a new session at midnight. Other sessionization schemes might not impose this restriction.

PL/SQL weekly Aggregation Logic with dynamic time range

I need to aggregate the values at weekly interval. My date range is dynamic means i can give any start date and end date. Every sunday should be the starting week of every month. say if i have two columns and my start and end date is 07/11/2016 to 13/11/2016
column A column B
07/11/2016 23
08/11/2016 20
09/11/2016 10
10/11/2016 05
11/11/2016 10
12/11/2016 20
13/11/2016 10
My result should come like taking the average of column B
Column A Column B
13/11/2016 14.00
It means i should consider the past value and aggregate it to the day Sunday of that week. Also if my start and end date is like 07/11/2016 to 10/11/2016 then I should not aggregate the value as my week is not complete. I am able to aggregate the values but if my week is not complete i m not able to restrict the aggregation.
Is there any way to do this in PL/SQL??
Thank you in advance.
select to_char(columnA, 'iw') as weeknumber, avg(columnB)
from table
group by to_char(columnA, 'iw');
This will aggregate by number of week. If you need to show last day of week as a label you can get it as max(columnA) over (partition by to_char(columnA, 'iw'))

Calculate the week ending date in oracle using Saturday as the week end date

Given a field in Oracle that contains dates, how would you calculate what the week ending date is using Sun thru Sat as your week. For example, if the date is 1/26/2015 (which is a Monday), the query should return 1/31/2015 (which is a Saturday. If the date is 1/31/2015, then the query should return 1/31/2015.
Given any particular date / time value, this expression will return midnight of the preceding Sunday.
TRUNC(whatever_time,'DAY')
So, you can do stuff like this:
SELECT TRUNC(whatever_time,'DAY') week_starting,
TRUNC(whatever_time,'DAY') + 6 week_ending,
SUM(sales)
FROM table
GROUP BY TRUNC(whatever_time,'DAY')
and you'll get what you need.
Notice that TRUNC(whatever_time,'DAY') honors the Oracle session initialization parameter called “NLS_TERRITORY”. For example, in Europe Monday is considered the first business day of the week. Try this.
ALTER SESSION SET NLS_TERRITORY=GERMANY;
SELECT TRUNC( DATE '2013-12-31', 'DAY'),
TRUNC( DATE '2014-01-03', 'DAY')
FROM DUAL;
A complete writeup of this is here: http://www.plumislandmedia.net/sql-time-processing/using-sql-report-time-intervals-oracle/

Get records from database ordered by year > month > day

I have an Item model.
There are many records in the database with column created_at filled in.
I want to generate a view with such a hierarchy:
2014
December
31
items here
30
items here
29
items here
...
November
31
...
...
2013
...
What's the most elegant way to do that?
EDIT: Thank you so much for queries. How do I get that worked in Ruby on Rails?
To achieve this, we will order the records by the parts of date. Sample query below
SELECT
ItemDescription,
Year(DateField) AS Year,
Datename(mm, DateField) AS Month,
Day(DateField) AS Day
FROM tblName
ORDER BY
Year(DateField) DESC,
Month(DateField) DESC,
Day(DateField) DESC
This will provide you the data in the order expected. Now you can either create a stored procedure to modify the output to the format you need.
SELECT DATEPART(Year, PaymentDate) Year, DATEPART(Month, PaymentDate) Month, DATEPART(day, PaymentDate) Day,item_name
FROM Payments
GROUP BY DATEPART(Year, PaymentDate), DATEPART(Month, PaymentDate),DATEPART(day, PaymentDate) desc
ORDER BY Year, Month,day

Resources