BigQuery: create array with dates of specified range - google-bigquery

Does anyone know how to create an array in BigQuery containing dates of a specified range (where only the start and end date are needed to create the dates), like this:
[CURRENT_DATE(), DATE_ADD(CURRENT_DATE(), INTERVAL 1 DAY), DATE_ADD(CURRENT_DATE(), INTERVAL 2 DAY), DATE_ADD(CURRENT_DATE(), INTERVAL 3 DAY), DATE_ADD(CURRENT_DATE(), INTERVAL 4 DAY), DATE_ADD(CURRENT_DATE(), INTERVAL 5 DAY)]

This should work.
select generate_date_array("2021-05-01", "2021-05-30") as date_array
Output JSON
[
{
"date_array": [
"2021-05-01",
"2021-05-02",
"2021-05-03",
"2021-05-04",
"2021-05-05",
"2021-05-06",
"2021-05-07",
"2021-05-08",
"2021-05-09",
"2021-05-10",
"2021-05-11",
"2021-05-12",
"2021-05-13",
"2021-05-14",
"2021-05-15",
"2021-05-16",
"2021-05-17",
"2021-05-18",
"2021-05-19",
"2021-05-20",
"2021-05-21",
"2021-05-22",
"2021-05-23",
"2021-05-24",
"2021-05-25",
"2021-05-26",
"2021-05-27",
"2021-05-28",
"2021-05-29",
"2021-05-30"
]
}
]

Related

Incrementing Date - SQL(Snowflake)

I want to Increment/Decrement the Year , Day , Month by pulling in the Current Date in Snowflake in a single query ?
For e.g.
Suppose Current System Date - 04082021 I want to make it 05092022. I have tried the dateadd function but I suppose it allows only one part i.e. either year or month or day to be incremented at once.
Is it Possible ? If Not, What are the other alternatives ?
If you want to useDATEADD function, here is the code:
SELECT DATEADD(YEAR,+1,DATEADD(MONTH,+1,DATEADD(DAY,+1,CURRENT_DATE())));
returns 2022-09-05 from 2021-08-04
If you want to keep your format, Please use following code
SELECT TO_CHAR(DATEADD(YEAR,+1,DATEADD(MONTH,+1,DATEADD(DAY,+1,CURRENT_DATE()))),'DDMMYYYY');
I would do the arithmetic in thee parts:
select current_date + interval '1 year' + interval '1 month' + interval '1 day'
You can also use:
select current_date + interval '1 year, 1 month, 1 day'

Oracle SQL Developer showing last 90 days of data

im trying to get a query working that will show the last 90 days of data. this is my timestamp code(it was a unix timestamp) :
"" to_date('1970-01-01','YYYY-MM-DD') +
numtodsinterval(c.f_crtm,'SECOND')- 6/24 as "oracle date" ""
this is the format of my date when the above code is run: 21-JUN-2020 15:48:59
i know it has something to do with the SYSDATE -90 but i cant figure it out.
any help would be great.
I am thinking of something like this:
(date '1970-01-01' + c.f_crtm * interval '1' second) - interval '6' hour > sysdate - interval '90' day
Or to use an index on (f_crtm), you can rearrange the logic:
c.f_crtm > (trunc(sysdate - interval '90' day + interval '6 hour') - date '1970-01-01')*24*60*60

BigQuery StandardSQL: Last 7 Days using _TABLE_SUFFIX

Question: I want to pull data from multiple Google Analytics sessions tables using _TABLE_SUFFIX, but I want to set the suffix parameters to between "seven days ago" and "one day ago" (i.e. pulling data for the last 7 days)
The current syntax (that doesn't work):
#StandardSQL
SELECT
date,
SUM (totals.visits) AS visits
FROM
`projectname.123456789.ga_sessions_*`
WHERE
_TABLE_SUFFIX BETWEEN
'DATE_ADD(CURRENT_TIMESTAMP(), INTERVAL -7 DAY)' AND
'DATE_ADD(CURRENT_TIMESTAMP(), INTERVAL -1 DAY)'
GROUP BY
date
ORDER BY
date ASC
Which gives me the message "Valid: This query will process 0 B when run." To my eyes, there is no error in the syntax, but BigQuery is unable ot read my date functions and thus unable to suffix them to the ga_sessions_* wildcard
Inspiration:
BigQuery Cookbook has an example for legacySQL that I have been basing this on: (https://support.google.com/analytics/answer/4419694?hl=en#7days)
#LegacySQL
SELECT
date,
SUM (totals.visits) AS visits
FROM
(TABLE_DATE_RANGE([73156703.ga_sessions_],
DATE_ADD(CURRENT_TIMESTAMP(), -7, 'DAY'),
DATE_ADD(CURRENT_TIMESTAMP(), -1, 'DAY')))
GROUP BY
date
ORDER BY
date ASC
Things I've tried: (that doesn't work)
Using DATE_SUB instead of DATE_ADD and using CURRENT_DATE instead of CURRENT_TIMESTAMP:
WHERE
_TABLE_SUFFIX BETWEEN
'DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)' AND
'DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)'
Resulting in "Valid: This query will process 0 B when run."
Using DATE_FORMAT around DATE_SUB and CURRENT_DATE in order to get the dates without dashes:
WHERE
_TABLE_SUFFIX BETWEEN
'FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY))' AND
'FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))'
Resulting in "Valid: This query will process 0 B when run."
Tried skippingt he hyphens '' around the DATE_SUB clause
WHERE
_TABLE_SUFFIX BETWEEN
DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY) AND
DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
Resulting in the following error message "Error: No matching signature for operator BETWEEN for argument types: STRING, DATE, DATE. Supported signature: (ANY) BETWEEN (ANY) AND (ANY)"
Thanks in advance,
Elliott's answer is correct, but if you want to get the most performance out of BigQuery for such kind of query, instead of converting _TABLESUFFIX to DATE, you should convert CURRENT_DATE expressions to strings:
WHERE
_TABLE_SUFFIX BETWEEN
FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)) AND
FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY))
You were almost there with your last attempt. You need to convert your string to a date in order to use it in the comparison:
WHERE
PARSE_DATE('%Y%m%d', _TABLE_SUFFIX) BETWEEN
DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY) AND
DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
This works for anyone just looking to segment out the last week of data in big query. Works for any data set as long as you have a timestamp!
where TIMESTAMPFIELD >= TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 7 DAY)
If you also want to include today's data, use the intraday table:
Google Analytics: (docs)
SELECT *
FROM `myproject.xxxxxxx.ga_sessions_*`
WHERE _TABLE_SUFFIX BETWEEN
FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)) AND
FORMAT_DATE("intraday_%Y%m%d", CURRENT_DATE())
Google Analytics for Firebase: (docs)
SELECT *
FROM `myproject.analytics_xxxxxxx.events_*`
WHERE _TABLE_SUFFIX BETWEEN
FORMAT_DATE("%Y%m%d", DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)) AND
FORMAT_DATE("intraday_%Y%m%d", CURRENT_DATE())

How to get the last day of month in postgres?

How to find the last day os the month in postgres?
I have a date columns stored as numeric(18) in the format(YYYYMMDD)
I am trying it to make it date using
to_date("act_dt",'YYYYMMDD') AS "act date"
then find the last day of this date:
like this:
(select (date_trunc('MONTH',to_date("act_dt",'YYYYMMDD')) + INTERVAL '1 MONTH - 1 day')::date)
but it gives me this error:
ERROR: Interval values with month or year parts are not supported
Detail:
-----------------------------------------------
error: Interval values with month or year parts are not supported
code: 8001
context: interval months: "1"
query: 673376
location: cg_constmanager.cpp:145
process: padbmaster [pid=20937]
-----------------------------------------------
Any help?
Postgres version:
PostgreSQL 8.0.2 on i686-pc-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3), Redshift 1.0.874
For anybody coming to this question looking for the Postgres way to do this (not using Redshift), here's how you'd do it:
SELECT (date_trunc('month', '2017-01-05'::date) + interval '1 month' - interval '1 day')::date
AS end_of_month;
Replacing the '2017-01-05' with whatever date you want to use. You can make this into a function like this:
create function end_of_month(date)
returns date as
$$
select (date_trunc('month', $1) + interval '1 month' - interval '1 day')::date;
$$ language 'sql'
immutable strict;
EDIT Postgres 11+
Pulling this out of the comments from #Gabriel, you can now combine interval expressions in one interval (which makes things a little shorter):
select (date_trunc('month', now()) + interval '1 month - 1 day')::date as end_of_month;
-- +--------------+
-- | end_of_month |
-- +--------------+
-- | 2021-11-30 |
-- +--------------+
-- (1 row)
If you're using Amazon AWS Redshift then you can use Redshift's LAST_DAY function. While Redshift is based on PostgreSQL, the LAST_DAY function is not available in PostgreSQL, for a solution for PostgreSQL see #wspurgin's answer.
https://docs.aws.amazon.com/redshift/latest/dg/r_LAST_DAY.html
LAST_DAY( { date | timestamp } )
LAST_DAY returns the date of the last day of the month that contains date. The return type is always DATE, regardless of the data type of the date argument.
For example:
SELECT LAST_DAY( TO_DATE( act_date, 'YYYYMMDD' ) )
Okay, so you've got a numeric(18) column containing numbers like 20150118. You can convert that to a date like:
to_date(your_date_column::text, 'YYYYMMDD')
From a date, you can grab the last day of the month like:
(date_trunc('month', your_date_column) +
interval '1 month' - interval '1 day')::date;
Combined, you'd get:
select (date_trunc('month', to_date(act_dt::text, 'YYYYMMDD')) +
interval '1 month' - interval '1 day')::date
from YourTable;
Example at SQL Fiddle.
date_trunc('month',current_date) + interval '1 month' - interval '1 day'
Truncating any date or timestamp to the month level will give you the first of the month containing that date. Adding a month gives you the first of the following month. Then, removing a day will give you the date of the last day of the month of the provided date.
For future searches, Redshift does not accept INTERVAL '1 month'. Instead use dateadd(month, 1, date) as documented here.
To get the end of the month use: DATEADD(DAY, -1, (DATE_TRUNC('month', DATEADD(MONTH, 1, date))))
select to_char(date_trunc('month', now() + '01 Months'::interval) - '01 Days'::interval, 'YYYYmmDD'::text)::numeric as end_period_n

sql query with date intevals

Hi I need help to create a query that return a result based on date interval but I can't get it to work correctly.
I would like to achieve a result giving me the records with a date that are within a historic time span:
day -1 to -7 */from yesterday and -7 days */
day -8 to -14 */the date is between -8 and -14 days from today
For the first interval I use this where clause:
...
where `invoiceExpDate` >= date_add(now(), INTERVAL - 7 DAY)
how can I modify this to NOT give me the records for today??
For the second interval I use:
...
where datediff(invoiceExpDate,now())<= 14
AND datediff(invoiceExpDate,now())> 7
AND `invoiceExpDate` > now()
I can't get them to work. CAn you help me with the correct where clause to return what I want?
Thanks
I think you can combine date_add() and BETWEEN
For your first clause
...
WHERE `invoiceExpDate` BETWEEN
date_add(now(), INTERVAL - 7 DAY) AND
date_add(now(), INTERVAL - 1 DAY)
Similar pattern for the second.
LogDate BETWEEN DATEADD(dd, -7, GETDATE()) AND
DATEADD(dd, -1, GETDATE())