Aggregate on relative daterange in Oracle SQL - sql

I have a table with several columns I would like to aggregate on, I have already aggregated on absolute days, but now I want to aggregate relatively. In my table I have a timestamp, and I would like to group by a date range so that the datestamp's day is 0, the day after 1 and so forth.
SELECT count(*) num_elements, sum(some_value) like_to_sum, reldate
FROM the_large_table
GROUP BY *** what goes here *** reldate.
Can I aggregate on the return from a function, or is there a better way to approach this problem.
If I can aggregate on the result from a function, are there any functions for this already in SQL, or how could this be solved?

SELECT
COUNT(*) AS num_elements,
SUM(some_value) AS like_to_sum,
TRUNC(SYSDATE) - TRUNC(your_date) AS rel_date
FROM the_large_table
GROUP BY TRUNC(SYSDATE) - TRUNC(your_date);

Related

PrestoDB: select all dates between two dates

I need to form a report which provides some information per each date within dates interval.
I need to have it within a single query (can't create any functions or supporting tables).
How can I achieve that in PrestoDB?
Note: There are lots of vendor specific solution here, here and even here. But none of them satisfies my need as they either don't work in Presto or use tables/functions.
To be more precise here is an example of query:
WITH ( query to select all dates between 2017.01.01 and 2018.01.01 ) AS dates
SELECT
date date,
count(*) number_of_orders
FROM dates dates
LEFT JOIN order order
ON order.created_at = dates.date
You can use the Presto SEQUENCE() function to generate a sequence of days as an array, and then use UNNEST to explode that array as a result set.
Something like this should work for you:
SELECT date_array AS DAY
FROM UNNEST(
SEQUENCE(
cast('2017-01-01' AS date),
cast('2018-01-01' AS date),
INTERVAL '1' DAY
)
) AS t1(date_array)

Is there a way to turn these multiple SQL queries into one?

I have a query that looks like this:
SELECT COUNT(*)
FROM table
WHERE date_field >= '2018-04-08'
AND date_field <= '2018-04-14'
I need to do this 26 times, for the current week and for 25 previous weeks, with each result separated by a carriage return. Is this possible with a single SQL query or do I need to put it in a loop, as I'm now doing?
Note that this is in FileMaker. I don't think that's relevant, but now you know, just in case.
Look into using "group by". Assuming that you are looking at calendar weeks, grouping by the week of the date will give you the counts per week and an extra condition can limit the overall range.
FileMaker has a WeekOfYearFiscal() function. 2nd parameter is the day of week start date.
SELECT WeekOfYearFiscal(dateField;2), COUNT(*)
FROM table
WHERE date_field >= '2018-01-01'
AND date_field <= '2018-04-14'
group by WeekOfYearFiscal(dateField;2)
See this documentation - http://www.filemaker.com/help/12/fmp/html/func_ref1.31.28.html
Give this a go. If the GROUP BY doesn't work on the function, you can nest the inner part and give an alias.

How to generate Month list in PostgreSQL?

I have a table A with startdate column which is TIMESTAMP WITHOUT TIME ZONE I need to write a query/function that generate a list of months from the MIN value of the column till MAX value of the column.
For example:
startdate
2014-12-08
2015-06-16
2015-02-17
will generate a list of: (Dec-14,Jan-15,Feb-15,Mar-15,Apr-15,May-15,Jun-15)
How do I do that? I never used PostgreSQL to generate data that wasn't there... it always has been finding the correct data in the DB... any ideas how to do that? Is it doable in a query?
For people looking for an unformatted list of months:
select * from generate_series('2017-01-01', now(), '1 month')
You can generate sequences of data with the generate_series() function:
SELECT to_char(generate_series(min, max, '1 month'), 'Mon-YY') AS "Mon-YY"
FROM (
SELECT date_trunc('month', min(startdate)) AS min,
date_trunc('month', max(startdate)) AS max
FROM a) sub;
This generates a row for every month, in a pretty format. If you want to have it like a list, you can aggregate them all in an outer query:
SELECT string_agg("Mon-YY", ', ') AS "Mon-YY list"
FROM (
-- Query above
) subsub;
SQLFiddle here

Aggregate function -Avg is not working in my sql query

In my query I need to display date and average age:
SELECT (SYSDATE-rownum) AS DATE,
avg((SYSDATE - rownum)- create_time) as average_Age
FROM items
group by (SYSDATE-rownum)
But my output for average age is not correct. It's simply calculating/displaying the output of (SYSDATE - rownum)- create_time but not calculating the average of them though I use: avg((SYSDATE - rownum)- create_time).
Can someone tell me why the aggregate function AVG is not working in my query and what might be the possible solution
In the select clause you are using both an non-aggregate expression as wel as an aggregate expression. By dropping the (SYSDATE-rownum) AS DATE statemant you would generate an outcome over the whole data set. In that way the avg is calculated over the whole data set ... and not just per single record retrieve.
Then you might drop the group by too. In the end you just keep the avg statement
SELECT avg((SYSDATE - rownum)- create_time) as average_Age
FROM items
First you need to think on rows or group on which you need avg. this column will come in group by clause. as a simple thing if there is 5 rows with age of 20, 10, 20, 30 then avg will be (80/4=20) i.e. 20. so I think you need to fist calculate age by (sysdate - create_time).
eg.select months_between(sysdate,create_date)/12 cal3 from your_table
and then there will be outer query for avg on group.

Using a timestamp function in a GROUP BY

I'm working with a large transaction data set and would like to group a count of individual customer transactions by month. I am unable to use the timestamp function in the GROUP BY and return the following error:
BAD_QUERY (expression STRFTIME_UTC_USEC([DATESTART], '%b') in GROUP BY is invalid)
Is there a simple workaround to achieve this or should I build a calendar table (which may be the simplest option)?
You have to use an alias:
SELECT STRFTIME_UTC_USEC(DATESTART, '%b') as month, COUNT(TRANSACTION)
FROM datasetId.tableId
GROUP BY month
#Charles is correct but as an aside you can also group by column number.
SELECT STRFTIME_UTC_USEC(DATESTART, '%b') as month, COUNT(TRANSACTION) as count
FROM [datasetId.tableId]
GROUP BY 1
ORDER BY 2 DESC