#sql #google-cloud-platform #google-bigquery
#sql #google-облачная платформа #google-bigquery
Вопрос:
Можно ли реорганизовать этот SQL?
SELECT
field1,
field2,
contact
FROM
`mytable`
WHERE
concat = CONCAT(
(EXTRACT(YEAR FROM DATE_SUB(current_date(), INTERVAL 2 DAY))-1),"/",
EXTRACT(WEEK(MONDAY) FROM DATE_SUB(current_date(), INTERVAL 2 DAY)),"/",
EXTRACT(DAYOFWEEK FROM DATE_SUB(current_date(), INTERVAL 2 DAY)))
OR
concat = CONCAT(
(EXTRACT(YEAR FROM DATE_SUB(current_date(), INTERVAL 3 DAY))-1),"/",
EXTRACT(WEEK(MONDAY) FROM DATE_SUB(current_date(), INTERVAL 3 DAY)),"/",
EXTRACT(DAYOFWEEK FROM DATE_SUB(current_date(), INTERVAL 3 DAY)))
OR ...
OR ...
OR ... same function, just the INTERVAL value changes
Я пытался увидеть ЦИКЛЫ в bigquery, GENERATE_ARRAY и других вещах, но я не могу достичь своей цели: (
Заранее благодарю вас за помощь! 🙂
Ответ №1:
Ниже приведен стандартный SQL для BigQuery
#standardSQL
create temp function all_conditions(intervals int64) as (
array(
select concat(
(extract(year from date_sub(current_date(), interval value day))-1),"/",
extract(week(monday) from date_sub(current_date(), interval value day)),"/",
extract(dayofweek from date_sub(current_date(), interval value day)))
from unnest(generate_array(1, intervals)) value
)
);
select
field1,
field2,
contact
from `mytable`
where concat in unnest(all_conditions(10))
Ответ №2:
Я не уверен, можете ли вы обернуть OR, который вы используете внутри цикла. Вы также можете попробовать использовать определяемую пользователем функцию (UDF). Использование UDF сделало бы его уже намного более читаемым и компактным. Оберните свой повторяющийся синтаксис SQL в функцию, которая будет выглядеть примерно так:
CREATE TEMP FUNCTION extractInterval(x INT64) AS (
CONCAT(
(EXTRACT(YEAR FROM DATE_SUB(current_date(), INTERVAL x DAY))-1),"/",
EXTRACT(WEEK(MONDAY) FROM DATE_SUB(current_date(), INTERVAL x DAY)),"/",
EXTRACT(DAYOFWEEK FROM DATE_SUB(current_date(), INTERVAL x DAY)))
);
Затем используйте эту функцию в своем запросе:
SELECT
field1,
field2,
contact
FROM
`mytable`
WHERE
concat = extractInterval(2)
OR
concat = extractInterval(3)
OR
...
Ответ №3:
Вы можете использовать GENERATE_DATE_ARRAY
для построения своего диапазона дат и присоединить его к своему основному запросу или использовать что-то вроде where concat in (select ywd_string from date_range)
with date_range as (
SELECT day as filler_date
, CONCAT(
(EXTRACT(YEAR FROM Day)-1),"/",
EXTRACT(WEEK(MONDAY) FROM day),"/",
EXTRACT(DAYOFWEEK FROM day)) as ywd_string
FROM UNNEST(
GENERATE_DATE_ARRAY(DATE('2020-06-20'), DATE('2020-09-19'), INTERVAL 1 DAY)
) AS day
)