Big query error:Failed to parse input string - google-bigquery

Using Standard sql query but getting subject mentioned error(Failed to parse input string).
#standardSQL
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_week,
EXTRACT(WEEK FROM date) AS week_of_year,
FORMAT_DATE("%y-%m", date) AS yyyymm
FROM(
SELECT PARSE_DATE('%y%m%d', date) date, campaign
FROM `tech-team-staging-2019.DFW_GA_Data_v1_05122019.DFW_G_Analytics_Predicted_data_v1_05122019`
GROUP BY 1,2
)

Below is for BigQuery Standard SQL
Note: it is not clear what your data field look like - so below are the options
in case if your date field is a string with YYYY-MM-DD - you should use below
#standardSQL
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_week,
EXTRACT(WEEK FROM date) AS week_of_year,
FORMAT_DATE("%Y-%m", date) AS yyyymm
FROM(
SELECT PARSE_DATE('%Y-%m-%d', date) date, campaign
FROM `tech-team-staging-2019.DFW_GA_Data_v1_05122019.DFW_G_Analytics_Predicted_data_v1_05122019`
GROUP BY 1,2
)
in case if it is - YY-MM-DD
#standardSQL
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_week,
EXTRACT(WEEK FROM date) AS week_of_year,
FORMAT_DATE("%Y-%m", date) AS yyyymm
FROM(
SELECT PARSE_DATE('%y-%m-%d', date) date, campaign
FROM `tech-team-staging-2019.DFW_GA_Data_v1_05122019.DFW_G_Analytics_Predicted_data_v1_05122019`
GROUP BY 1,2
)
finally, if it is YYMMDD
#standardSQL
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_week,
EXTRACT(WEEK FROM date) AS week_of_year,
FORMAT_DATE("%Y-%m", date) AS yyyymm
FROM(
SELECT PARSE_DATE('%y%m%d', date) date, campaign
FROM `tech-team-staging-2019.DFW_GA_Data_v1_05122019.DFW_G_Analytics_Predicted_data_v1_05122019`
GROUP BY 1,2
)
and yet one more - YYYYMMDD
#standardSQL
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_week,
EXTRACT(WEEK FROM date) AS week_of_year,
FORMAT_DATE("%Y-%m", date) AS yyyymm
FROM(
SELECT PARSE_DATE('%Y%m%d', date) date, campaign
FROM `tech-team-staging-2019.DFW_GA_Data_v1_05122019.DFW_G_Analytics_Predicted_data_v1_05122019`
GROUP BY 1,2
)

Related

Difference between two dates in business days? Google Bigquery

How do I calculate the difference between two dates in business days in Google Bigquery?
I want to replicate this example below:
I have tried these examples but they do not give the expected results:
DATE_DIFF but only counting business days
I also used this logic,ionand it did not work:
CREATE TEMP FUNCTION BusinessDateDiff(start_date DATE, end_date DATE) AS (
(SELECT COUNTIF(MOD(EXTRACT(DAYOFWEEK FROM date), 7) > 1)
FROM UNNEST(GENERATE_DATE_ARRAY(
start_date, DATE_SUB(end_date, INTERVAL 1 DAY))) AS date)
);
Consider below
create temp function BusinessDateDiff(delivery DATE, eta DATE) AS ((
select if(delivery > eta, 1, -1) * count(*)
from unnest(generate_date_array(
least(delivery, eta), greatest(delivery, eta) - 1
)) day
where not extract(dayofweek from day) in (1, 7)
));
select *,
BusinessDateDiff(DELIVERY_DATE, ORIGINAL_ETA_DATE) as BUSINESS_DAYS
from your_table
if applied to sample data as in your question - output is
getting desired result as follows:
CREATE TEMP FUNCTION BusinessDateDiff(start_date DATE, end_date DATE) AS (
(SELECT -1*COUNTIF(MOD(EXTRACT(DAYOFWEEK FROM date), 7) > 1)
FROM UNNEST(GENERATE_DATE_ARRAY( start_date , DATE_SUB(end_date,INTERVAL 1 DAY))) AS date));
CREATE TEMP FUNCTION BusinessDateDiff1( end_date DATE, start_date DATE) AS (
(SELECT COUNTIF(MOD(EXTRACT(DAYOFWEEK FROM date), 7) > 1)
FROM UNNEST(GENERATE_DATE_ARRAY( end_date , DATE_SUB(start_date,INTERVAL 1 DAY))) AS date));
WITH OrdersTable AS (
SELECT DATE '2022-06-28' AS DELIVERY_DATE,
DATE '2022-08-17' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-07-01' AS DELIVERY_DATE,
DATE '2022-07-14' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-30' AS DELIVERY_DATE,
DATE '2022-07-08' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-30' AS DELIVERY_DATE,
DATE '2022-07-08' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-29' AS DELIVERY_DATE,
DATE '2022-07-06' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-27' AS DELIVERY_DATE,
DATE '2022-07-01' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-30' AS DELIVERY_DATE,
DATE '2022-07-05' AS ORIGINAL_ETA_DATE
UNION ALL
SELECT DATE '2022-06-30' AS DELIVERY_DATE,
DATE '2022-06-28' AS ORIGINAL_ETA_DATE
)
SELECT
DELIVERY_DATE,
ORIGINAL_ETA_DATE,
case when DELIVERY_DATE < ORIGINAL_ETA_DATE then
BusinessDateDiff(DELIVERY_DATE, ORIGINAL_ETA_DATE)
when DELIVERY_DATE > ORIGINAL_ETA_DATE then
BusinessDateDiff1(ORIGINAL_ETA_DATE, DELIVERY_DATE)
else 0 end AS BUSINESS_DAYS
FROM OrdersTable
[![Desired Result][1]][1]
[1]: https://i.stack.imgur.com/efmw3.png

I would like to extract the month and day from a date

My code
SELECT
PARSE_DATE('%Y%m%d', CAST(date AS STRING)) AS date,
EXTRACT(DAY from date) AS day_of_month,
EXTRACT(MONTH from date) AS week_of_year,
channelGrouping, deviceCategory, sessions, conversions,
I would like to turn the date's in my column which is in the form 20170101 into 2017-01-01.
Then I would like to extract the month and day from this. However I keep getting an error:
No matching signature for function EXTRACT for argument types: DATE_TIME_PART FROM INT64. Supported signatures: EXTRACT(DATE_TIME_PART FROM DATE); EXTRACT(DATE_TIME_PART FROM TIMESTAMP [AT TIME ZONE STRING]); EXTRACT(DATE_TIME_PART FROM DATETIME); EXTRACT(DATE_TIME_PART FROM TIME) at [1:60]
Below few options for BigQuery Standard SQL - to avoid multiple pre-parsing
Option 1
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_month,
EXTRACT(WEEK FROM date) AS week_of_year,
channelGrouping, deviceCategory, sessions, conversions,
FROM `project.dataset.table`,
UNNEST([PARSE_DATE('%Y%m%d', CAST(date AS STRING))]) date
Option 2
SELECT
date,
EXTRACT(DAY FROM date) AS day_of_month,
EXTRACT(WEEK FROM date) AS week_of_year,
channelGrouping, deviceCategory, sessions, conversions,
FROM (
SELECT * REPLACE(PARSE_DATE('%Y%m%d', CAST(date AS STRING)) AS date)
FROM `project.dataset.table`
)
You need to re-parse the date for each extract():
SELECT PARSE_DATE('%Y%m%d', CAST(date AS STRING)) as date,
EXTRACT(DAY from PARSE_DATE('%Y%m%d',
EXTRACT(MONTH from PARSE_DATE('%Y%m%d', CAST(date AS STRING))) as week_of_year,
channelGrouping, deviceCategory, sessions, conversions,
However, if the date is already a number in YYYYMMDD format, why not just use arithmetic functions:
select mod(date, 100) as day,
mod(floor(date / 100), 100) as month

How to write an SQL aggregate function/query

I have a query that displays the total value (sum of amount) for each day.
The query:
SELECT CAST(date AS DATE), SUM(amount) AS total_amount FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
The CAST is to abbreviate the datetime format to just a date.
Now I want to select only the day which has the highest sum with the max function.
To do this I tried writing the following aggregate query:
SELECT s.date, s.total_amount
FROM (SELECT CAST(date AS DATE), SUM(amount) AS total_amount FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)) s
WHERE s.total_amount = (SELECT MAX(s.total_amount) FROM table)
This does not work. I know the problem is with the final WHERE clause, but I need help with making it work.
Use ORDER BY with LIMIT :
SELECT CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
ORDER BY total_amount DESC
LIMIT 1;
If you are working with SQL Server then you can use TOP :
SELECT TOP (1) CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
ORDER BY total_amount DESC;
If you want ties then you can use window function :
SELECT t.*
FROM (SELECT CAST(date AS DATE), SUM(amount) AS total_amount,
RANK() OVER (ORDER BY SUM(amount) DESC) as Seq
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
) t
WHERE seq = 1;
You can use CTE :
WITH CTE AS (
SELECT CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
)
SELECT c.*
FROM CTE C
WHERE C.total_amount = (SELECT MAX(total_amount) FROM CTE);
Note : If your DBMS doesn't support CTE expression then you need repeat the SELECT statement in Subquery.
SELECT CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
HAVING SUM(amount) = (SELECT MAX(total_amount)
FROM (SELECT CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
) t
);
If you are using SQL Server then you can use TOP
SELECT TOP 1 CAST(date AS DATE), SUM(amount) AS total_amount
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
ORDER BY total_amount DESC
Use window function row_number() - should work with MySQL 8.0, PostgreSQL, Oracle and SQL Server.
select
date,
total_amount
from
(
SELECT
CAST(date AS DATE) as date,
SUM(amount) AS total_amount,
row_number() over (order by SUM(amount) desc) as rnk
FROM table
WHERE date BETWEEN '2019-01-01 00:00:00' AND '2019-12-31 00:00:00'
GROUP BY CAST(date AS DATE)
) val
where rnk = 1
SELECT s.dt, s.total_amount
FROM (SELECT CAST(date AS DATE) as dt, SUM(amount) AS total_amount
FROM table
WHERE CAST(date as date) BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY CAST(date AS DATE)) s
WHERE s.total_amount = (Select max(total_amount)
FROM (SELECT CAST(date AS DATE) as dt, SUM(amount) AS total_amount
FROM table
WHERE CAST(date as date) BETWEEN '2019-01-01' AND '2019-12-31'
GROUP BY CAST(date AS DATE)) ss )

Visits per Isoweek in big query

I am trying to pull visits per isoweek from big query.
however I am failing with the date transformation.
Could you support?
StandardSQL
SELECT count (visitid) as Sessions, date,
EXTRACT (ISOYEAR FROM date) AS isoyear
FROM `xxx_*`
WHERE _TABLE_SUFFIX BETWEEN '201806020' AND '20180630'
GROUP BY date
order by date DESC
Have you tried a query like this?
SELECT EXTRACT(ISOYEAR FROM date) as yyyy,
EXTRACT(ISOWEEK FROM DATE) as ww,
COUNT(*) as Sessions
FROM `xxx_*`
WHERE _TABLE_SUFFIX BETWEEN '201806020' AND '20180630'
GROUP BY yyyy, ww
ORDER BY MIN(date) DESC;

postgreSQL: How Select the nearest date that is not null

I got a date that I want to find the all records in the past that got the same month and day.
The problem accrues when there is no such date in the same year. For example, the 29th February.
My goal is to get the nearest date from below the date that does not exist.
This is my currently query with the date 2012-02-29:
SELECT date, amount
FROM table_name
WHERE
EXTRACT(MONTH FROM date) = EXTRACT(MONTH FROM DATE('2012-02-29') )
AND EXTRACT(DAY FROM date) = EXTRACT(DAY FROM DATE('2012-02-29') )
AND date < '2012-02-29'
ORDER BY date DESC LIMIT 10;
If I understand correctly, you want one date per year with the property that that day is nearest to the given date.
I would suggest using distinct on:
select distinct on (date_trunc('year', date)) t.*
from table_name t
order by date_trunc('year', date),
abs(date_part('day, (date -
(date '2012-02-29' -
(extract(year from date '2012-02-29') - extract(year from date)) * interval '1 year'
)
)
)
)
);
EDIT:
An example of working code:
select distinct on (date_trunc('year', date)) t.*
from table_name t
order by date_trunc('year', date),
abs(date_part('day', date - (date '2012-02-29' -
((extract(year from date '2012-02-29') - extract(year from date)) * interval '1 year')
)
))