Объедините строки в стандартном SQL BigQuery, игнорируя значения NULL, и эффективно отфильтруйте строку - PullRequest
0 голосов
/ 28 ноября 2018

Это следующий за этот вопрос , который почти привел меня туда, но я бы хотел вернуть только те строки, которые содержат самый полный объем данных.

Расширение примера решенияиз вопроса, указанного выше:

#standardSQL
WITH `project.dataset.your_table` AS (
  SELECT 1 id, 'first_data' col_1, NULL col_2,  '4/22' updated UNION ALL
  SELECT 1,     NULL,             'old',        '4/23'         UNION ALL
  SELECT 1,     NULL,             'correct',    '4/24'         UNION ALL
  SELECT 1,    'next_data',       NULL,         '4/25'         UNION ALL
  SELECT 1,     NULL,             NULL,         '4/26'  
  SELECT 2,     NULL,             'old',        '4/23'         UNION ALL
  SELECT 2,     'this_one',        NULL,        NULL,          UNION ALL            
)
SELECT id, 
  IFNULL(col_1, FIRST_VALUE(col_1 IGNORE NULLS) OVER(win)) col_1, 
  IFNULL(col_2, FIRST_VALUE(col_2 IGNORE NULLS) OVER(win)) col_2, 
  updated
FROM `project.dataset.your_table`
WINDOW win AS (PARTITION BY id ORDER BY updated DESC 
               ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
ORDER BY id, updated

Я бы хотел, чтобы результат выглядел следующим образом:

id  col_1       col_2   updated     
1   next_data   correct 4/26 
2   this_one    old     4/23

Я пробовал это с помощью ROW_NUMBER(), и это работает, но было предложено этоне очень эффективно использует память:

SELECT * EXCEPT(n) FROM (
    WITH `project.dataset.your_table` AS (
      SELECT 1 id, 'first_data' col_1, NULL col_2,  '4/22' updated UNION ALL
      SELECT 1,     NULL,             'old',        '4/23'         UNION ALL
      SELECT 1,     NULL,             'correct',    '4/24'         UNION ALL
      SELECT 1,    'next_data',       NULL,         '4/25'         UNION ALL
      SELECT 1,     NULL,             NULL,         '4/26'         UNION ALL
      SELECT 2,     NULL,             'old',        '4/23'         UNION ALL
      SELECT 2,     'this_one',        NULL,        NULL                     
    )
    SELECT id, 
      IFNULL(col_1, FIRST_VALUE(col_1 IGNORE NULLS) OVER(win)) col_1, 
      IFNULL(col_2, FIRST_VALUE(col_2 IGNORE NULLS) OVER(win)) col_2, 
      updated,
      ROW_NUMBER() OVER (PARTITION BY id) as n
    FROM `project.dataset.your_table`
    WINDOW win AS (PARTITION BY id ORDER BY updated DESC 
                   ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING)
    ORDER BY id, updated)
 WHERE n = 1

, что дает:

id  col_1       col_2   updated     
1   next_data   correct 4/26 
2   this_one    old     4/23

1 Ответ

0 голосов
/ 28 ноября 2018
#standardSQL
WITH `project.dataset.your_table` AS (
  SELECT 1 id, 'first_data' col_1, NULL col_2,  '4/22' updated UNION ALL
  SELECT 1,     NULL,             'old',        '4/23'         UNION ALL
  SELECT 1,     NULL,             'correct',    '4/24'         UNION ALL
  SELECT 1,    'next_data',       NULL,         '4/25'         UNION ALL
  SELECT 1,     NULL,             NULL,         '4/26'         UNION ALL
  SELECT 2,     NULL,             'old',        '4/23'         UNION ALL
  SELECT 2,     'this_one',        NULL,        NULL                 
)
SELECT id, 
  ARRAY_AGG(col_1 IGNORE NULLS ORDER BY updated DESC LIMIT 1)[SAFE_OFFSET(0)] col_1,
  ARRAY_AGG(col_2 IGNORE NULLS ORDER BY updated DESC LIMIT 1)[SAFE_OFFSET(0)] col_2,
  MAX(updated) updated
FROM `project.dataset.your_table`
GROUP BY id   

с результатом

Row id  col_1       col_2       updated  
1   1   next_data   correct     4/26     
2   2   this_one    old         4/23     
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...