Рекурсивное вычитание из двух отдельных таблиц для заполнения исторических данных - PullRequest
0 голосов
/ 07 апреля 2020

У меня есть два набора данных, размещенных в Snowflake, с количеством подписчиков в социальных сетях по дням. Основная таблица, которую мы будем использовать для продвижения вперед (follower_counts), показывает количество подписчиков по дням:

follower_counts

Эта таблица действительна по состоянию на 4/4/2020 и будет обновляться ежедневно. К сожалению, я не могу получить исторические данные в этом формате. Вместо этого у меня есть таблица с историческими данными (follower_gains), которая показывает net прирост подписчиков за день для нескольких учетных записей:

follower_gains

В идеале - я хочу взять значение follower_count с минимальной даты в текущей таблице (follower_counts) и вычесть сумму выигрышей (органик c + оплаченный выигрыш) за каждый день до минимальной даты таблицы follower_gains, чтобы заполнить исторически таблицу follower_count , Кроме того, в этих таблицах есть несколько учетных записей с данными, поэтому их необходимо сгруппировать по учетным записям. Это должно выглядеть так:

ideal_table

Я только дошел до объединения этих двух таблиц, но даже не знаю, с чего начать с циклическим прохождением этих строк:

WITH a AS (
SELECT
  account_id,
  date,
  organizational_entity,
  organizational_entity_type,
  vanity_name,
  localized_name,
  localized_website,
  organization_type,
  total_followers_count,
  null AS paid_follower_gain,
  null AS organic_follower_gain,
  account_name,
  last_update
FROM follower_counts
  UNION ALL
  SELECT
account_id,
  date,
  organizational_entity,
  organizational_entity_type,
  vanity_name,
  localized_name,
  localized_website,
  organization_type,
  null AS total_followers_count,
  organic_follower_gain,
  paid_follower_gain,
  account_name,
  last_update
  FROM follower_gains)
SELECT
a.account_id,
a.date,
a.organizational_entity,
a.organizational_entity_type,
a.vanity_name,
a.localized_name,
a.localized_website,
a.organization_type,
a.total_followers_count,
a.organic_follower_gain,
a.paid_follower_gain,
a.account_name,
a.last_update
FROM a 
ORDER BY date desc LIMIT 100

Ответы [ 2 ]

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

ОБНОВЛЕНИЕ: изменено union на union all и добавлено not exists для удаления дубликатов. Внесены изменения в соответствии с комментариями.

ПРИМЕЧАНИЕ: Пожалуйста, убедитесь, что вы не публикуете изображения таблиц. Трудно воссоздать ваш сценарий, чтобы написать правильный запрос. Протестируйте это решение и обновите его, чтобы я мог вносить изменения в случае необходимости.

Вы не loop до SQL, потому что это не процедурный язык. Заданная вами в запросе операция выполняется для всех строк в таблице.

with cte as (SELECT a.account_id,
              a.date,
              a.organizational_entity,
              a.organizational_entity_type,
              a.vanity_name,
              a.localized_name,
              a.localized_website,
              a.organization_type,
              (a.follower_count - (b.organic_gain+b.paid_gain)) AS follower_count,
              a.account_name,
              a.last_update,
              b.organic_gain,
              b.paid_gain
       FROM follower_counts a
       JOIN follower_gains b ON a.account_id = b.account_id
       AND b.date < (select min(date) from 
       follower_counts c where a.account.id = c.account_id) 
       )
    SELECT b.account_id,
          b.date,
          b.organizational_entity,
          b.organizational_entity_type,
          b.vanity_name,
          b.localized_name,
          b.localized_website,
          b.organization_type,
          b.follower_count,
          b.account_name,
          b.last_update,
          b.organic_gain,
          b.paid_gain
    FROM cte b
    UNION ALL
     SELECT a.account_id,
           a.date,
           a.organizational_entity,
           a.organizational_entity_type,
           a.vanity_name,
           a.localized_name,
           a.localized_website,
           a.organization_type,
           a.follower_count,
           a.account_name,
           a.last_update,
           NULL as organic_gain,
           NULL as paid_gain
    FROM follower_counts a where not exists (select 1 from 
    follower_gains c where a.account_id = c.account_id AND a.date = c.date)
0 голосов
/ 07 апреля 2020

Вы можете сделать что-то подобное, вместо использования переменной вы можете просто заключить ее в другую скобку и написать в конце ) AS FollowerGrowth

DECLARE @FollowerGrowth INT = 
( SELECT total_followers_count 
  FROM follower_gains 
  WHERE AccountID = xx  ) 
- 
( SELECT TOP 1 follower_count 
  FROM follower_counts 
  WHERE AccountID = xx 
  ORDER BY date ASCENDING ) 
...