Дата свертки через таблицу переходов с метками времени - как - PullRequest
0 голосов
/ 27 июня 2018

Нам нужно каждый день извлекать конволюцию с момента прошлого и до настоящего времени со списком булевых переходов устройства с метками времени. Окончательный вывод должен представлять собой таблицу, в которой есть запись date: device_id для каждого дня, когда он находится в сети (в противном случае записи на эту дату нет).

Вот пример таблицы переходов для одного устройства:

Device Transition Table

Чтобы создать календарь свертки:

  calendar AS (
    SELECT day
    FROM UNNEST (GENERATE_DATE_ARRAY('2011-05-15', CURRENT_DATE())) AS day
  ),

Затем, чтобы сгенерировать хотя бы таблицу, в которой есть только даты перехода ПОСЛЕ события перехода, чтобы впоследствии их можно было ранжировать и выбирать последним (CROSS JOIN здесь - чёрт!):

joined_with_cal AS (

SELECT 
  cal.day as online_date,
  otr.when_changed,
  otr.device_id,
  otr.is_online,
  otr.rank_by_date
FROM 
  calendar AS cal
CROSS JOIN 
  ordered_transitions otr
WHERE
  cal.day >= DATE(otr.when_changed)
),

Затем код, который пытается ранжировать и выбирать самую последнюю запись в разделе по метке времени (when_changed или ranked_by_date - ни один из них, похоже, не работает):

SELECT  
  online_date,
  when_changed,
  device_id,
  is_online,
  rank_by_date,
FROM (
  SELECT
    online_date,
    when_changed,
    device_id,
    is_online,
    rank_by_date,
    RANK() OVER (PARTITION BY device_id ORDER BY rank_by_date ASC) as final_rank
  FROM
    joined_with_cal
)
WHERE
  final_rank = 1 AND
  --  online_date < '2017-08-01' AND
  device_id = 419609
ORDER BY
  online_date,
  when_changed,
  device_id

Однако, это не работает и, очевидно, ужасно.

Может кто-нибудь предложить правильное, элегантное решение?

Заранее спасибо!

1 Ответ

0 голосов
/ 29 июня 2018

@ Михаил: спасибо за просмотр и извините, мое объяснение не было более ясным.

После обсуждения с коллегой я использовал самосоединение, которое, кажется, работает:

trans_as_range_not_first AS (

  SELECT
    t1.device_id,
    t1.rank_by_when,
    t2.when_changed as online_start,
    t1.when_changed as online_stop,
    t1.account_id,
    t1.account_name,
    t1.server_type
  FROM
    ordered_trans AS t1  -- lower in rank index, later in time
  LEFT JOIN
    ordered_trans AS t2  -- greater in rank index, earlier in time
  ON
    t1.device_id = t2.device_id AND 
    t1.rank_by_when+1 = t2.rank_by_when  -- current and next row
  WHERE
    t1.is_online = 0 AND t2.is_online = 1
  GROUP BY
    device_id,
    rank_by_when,
    online_start,
    online_stop,
    account_id,
    account_name,
    server_type
),
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...