Продолжайте существующую таблицу до конца месяца с прогнозными данными и обновляйте ежедневно - PullRequest
0 голосов
/ 23 апреля 2020

Я хотел бы создать новую таблицу в Google Big Query с существующими данными о ежедневном доходе и дополнить эту новую таблицу прогнозными данными, которые основаны на существующих данных и должны быть созданы. Как только новые фактические данные существуют для определенного дня, они переопределяют данные прогноза на этот день. Кроме того, данные прогноза до конца месяца снова обновляются.

До сих пор я придумал следующее, которое генерирует сообщение об ошибке : Scalar subquery produced more than one element

    SELECT
        date, sum(yl_revenue), 'ACTUAL' as type 
        from project.dataset.table 
        where date >"2020-01-01" and date < current_date() 
        group by date 
        union distinct

        SELECT 
        (select calendar_date 
    FROM 
UNNEST(GENERATE_DATE_ARRAY('2020-01-01', DATE_SUB(DATE_TRUNC(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH), INTERVAL 1 DAY), INTERVAL 1 DAY)) 
AS calendar_date), 
        avg(revenue_daily) as average_daily_revenue, 
        'FORECAST' as type FROM 
            (SELECT sum(revenue) as revenue_daily from project.dataset.table 
    WHERE date > "2020-01-01" and extract(month from date) = extract (month from current_date()) group by date)

Как я sh данные выглядят так:

+------------+------------+----------+
|    date    |  revenue   |   type   |
+------------+------------+----------+
| 01.04.2020 | 100 €      | ACTUAL   |
| …          | 5.000 €    | ACTUAL   |
| 23.04.2020 | 200 €      | ACTUAL   |
| 24.04.2020 |  230,43 €  | FORECAST |
| 25.04.2020 |  230,43 €  | FORECAST |
| 26.04.2020 |  230,43 €  | FORECAST |
| 27.04.2020 |  230,43 €  | FORECAST |
| 28.04.2020 |  230,43 €  | FORECAST |
| 29.04.2020 |  230,43 €  | FORECAST |
| 30.04.2020 |  230,43 €  | FORECAST |
+------------+------------+----------+

На следующий день (24.04.2020) они должны выглядеть так:

+------------+--------------+----------+
|    date    |   revenue    |   type   |
+------------+--------------+----------+
| 01.04.2020 | 100 €        | ACTUAL   |
| …          | 5.000 €      | ACTUAL   |
| 23.04.2020 | 200 €        | ACTUAL   |
| 24.04.2020 |  1.000,00 €  | ACTUAL   | <----
| 25.04.2020 |  262,50 €    | FORECAST |
| 26.04.2020 |  262,50 €    | FORECAST |
| 27.04.2020 |  262,50 €    | FORECAST |
| 28.04.2020 |  262,50 €    | FORECAST |
| 29.04.2020 |  262,50 €    | FORECAST |
| 30.04.2020 |  262,50 €    | FORECAST |
+------------+--------------+----------+

Прогнозное значение - это просто сумма фактической выручки за месяц, деленная на количество дней, проведенных в этом месяце. Обратите внимание, что значение ежедневного прогноза изменилось во второй таблице, поскольку к нему добавлено новое фактическое значение.

Любая помощь в том, как подойти к этому, очень ценится!

Спасибо

Jan

Ответы [ 2 ]

1 голос
/ 23 апреля 2020

Когда новый день обновляется - вы можете запустить ниже, чтобы обновить остальные дни

UPDATE `project.dataset.table`
SET revenue = (
  SELECT ROUND(SUM(revenue) / COUNT(1), 2) 
  FROM `project.dataset.table`
  WHERE type = 'ACTUAL'
)
WHERE type = 'FORECAST'   

Выше предполагается, что у вас есть месячные таблицы со всеми днями, предварительно созданными в нем Если у вас другой макет - выше легко настраивается на это

0 голосов
/ 05 мая 2020

Я нашел решение своей проблемы. (Хотя, возможно, это не самая сложная из них)

Теперь у меня есть 3 новые таблицы:

  1. предоставляет даты прошлого и будущего, поэтому я назвал это «календарем»
  2. предоставляет данные о доходах за текущий месяц. Я перезаписываю эту таблицу каждый день запланированным запросом, который предоставляет фактические прошлые данные и прогнозируемые будущие данные (на основе фактических данных месяца) до конца текущего месяца.
  3. предоставляет прошлые данные (датируемые дольше, чем текущий месяц) плюс ежедневно обновляемые данные из 2). Я использую запланированный MERGE запрос для этого тоже.

Вот соответствующие запросы:

1)

SELECT
  *
FROM
  UNNEST(GENERATE_DATE_ARRAY('2018-01-01', '2030-12-31', INTERVAL 1 DAY)) AS calendar_date
WITH
OFFSET
  AS
OFFSET
ORDER BY
OFFSET

2)

SELECT
  date,
  'actual' AS type,
  ROUND(SUM(revenue),2)
FROM
  `project.dataset.revenue_data` 
WHERE
  EXTRACT(year
  FROM
    date) = EXTRACT (year
  FROM
    CURRENT_DATE())
  AND EXTRACT(month
  FROM
    date) = EXTRACT (month
  FROM
    CURRENT_DATE())
GROUP BY
  date
UNION DISTINCT
SELECT
  calendar_date,
  'forecast',
  (
  SELECT
    ROUND(AVG(revenue_daily),2)
  FROM (
    SELECT
      SUM(revenue) AS revenue_daily
    FROM
      `project.dataset.revenue_data`
    WHERE
      EXTRACT(year
      FROM
        date) = EXTRACT (year
      FROM
        CURRENT_DATE())
      AND EXTRACT(month
      FROM
        date) = EXTRACT (month
      FROM
        CURRENT_DATE())
    GROUP BY
      date
    ORDER BY
      date) AS average_daily_revenue),
FROM
  `project.dataset.calendar`
WHERE
  calendar_date >= CURRENT_DATE()
  AND calendar_date <=DATE_SUB(DATE_TRUNC(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH), MONTH), INTERVAL 1 DAY)
ORDER BY
  date

3)

MERGE
  `project.dataset.forecast_table` f
USING
  `project.dataset.forecast_month` m
ON
  f.date = m.date
  WHEN MATCHED THEN UPDATE SET f.type = m.type, f.revenue = m.revenue
  WHEN NOT MATCHED
  AND m.date >= CURRENT_DATE() THEN
INSERT
  (date,
    type,
    revenue)
VALUES
  (date, type, revenue)
...