Заполните пропущенные значения для объединенных таблиц в BigQuery - PullRequest
0 голосов
/ 04 октября 2018

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

WITH `trans` AS (
SELECT DATE '2018-10-02' trans_date, 10.0 quantity UNION ALL
SELECT DATE '2018-10-03', 5.0 UNION ALL
SELECT DATE '2018-10-05', 11.0 
),
`prices` AS (
SELECT DATE '2018-10-01' price_date, 1.0 price UNION ALL
SELECT DATE '2018-10-02', 2.0 UNION ALL
SELECT DATE '2018-10-03', 3.0 UNION ALL
SELECT DATE '2018-10-04', 4.0 UNION ALL
SELECT DATE '2018-10-05', 5.0 UNION ALL
SELECT DATE '2018-10-06', 6.0 UNION ALL
SELECT DATE '2018-10-07', 7.0 
)
SELECT 
price_date,
quantity, 
price
FROM (
SELECT price_date, quantity, price, trans_date FROM `trans`
RIGHT JOIN `prices`
ON trans.trans_date = prices.price_date
ORDER BY price_date
)

И я не могу понять, как заполнитьв последнем известном количестве, где нет транзакции на эту дату, чтобы получить результат примерно так:

price_date    quantity  price
2018-10-01    0.0    1.0
2018-10-02    10.0   2.0
2018-10-03    5.0    3.0
2018-10-04    5.0    4.0
2018-10-05    11.0   5.0
2018-10-06    11.0   6.0
2018-10-07    11.0   7.0

Следующим шагом будет вычисление значения во времени.Буду благодарен за любой пример / предложение, как это сделать.

РЕДАКТИРОВАТЬ: я добавил символ акций, чтобы соответствовать более реальный пример

WITH `trans` AS (
SELECT DATE '2018-10-02' trans_date, 10.0 quantity, 'TX' symbol UNION ALL
SELECT DATE '2018-10-03' trans_date, 5.0 quantity, 'TX' UNION ALL
SELECT DATE '2018-10-05', 11.0, 'AX' 
),
`prices` AS (
 SELECT DATE '2018-10-01' price_date, 1.0 price, 'TX' symbol UNION ALL
  SELECT DATE '2018-10-02', 2.0, 'TX' UNION ALL
  SELECT DATE '2018-10-03', 3.0, 'TX' UNION ALL
  SELECT DATE '2018-10-04', 4.0, 'TX' UNION ALL
  SELECT DATE '2018-10-05', 5.0, 'TX' UNION ALL
  SELECT DATE '2018-10-06', 6.0, 'TX' UNION ALL
  SELECT DATE '2018-10-07', 7.0, 'TX' UNION ALL
  SELECT DATE '2018-10-08', 8.0, 'AX' UNION ALL
  SELECT DATE '2018-10-09', 9.0, 'TX' UNION ALL
  SELECT DATE '2018-10-10', 10.0, 'AX' UNION ALL
  SELECT DATE '2018-10-11', 11.0, 'TX' UNION ALL
  SELECT DATE '2018-10-12', 12.0, 'TX' 
)

SELECT
  price_date, 
  t.symbol AS symbol,
  IFNULL(
    ARRAY_AGG(
      IF(p.price_date >= t.trans_date AND p.symbol = t.symbol, quantity, NULL) 
      IGNORE NULLS ORDER BY trans_date DESC LIMIT 1
      )[OFFSET(0)],
  -1234567890) quantity,
  price
FROM `prices` p
CROSS JOIN `trans` t
GROUP BY price_date, price, symbol
HAVING quantity != -1234567890
ORDER BY price_date   

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Ниже для BigQuery Standard SQL

#standardSQL
WITH `trans` AS (
  SELECT DATE '2018-10-02' trans_date, 10.0 quantity UNION ALL
  SELECT DATE '2018-10-03', 5.0 UNION ALL
  SELECT DATE '2018-10-05', 11.0 
),
`prices` AS (
  SELECT DATE '2018-10-01' price_date, 1.0 price UNION ALL
  SELECT DATE '2018-10-02', 2.0 UNION ALL
  SELECT DATE '2018-10-03', 3.0 UNION ALL
  SELECT DATE '2018-10-04', 4.0 UNION ALL
  SELECT DATE '2018-10-05', 5.0 UNION ALL
  SELECT DATE '2018-10-06', 6.0 UNION ALL
  SELECT DATE '2018-10-07', 7.0 
)
SELECT 
  price_date, 
  IFNULL(
    ARRAY_AGG(
      IF(p.price_date >= t.trans_date, quantity, NULL) 
      IGNORE NULLS ORDER BY trans_date DESC LIMIT 1
      )[OFFSET(0)],
  0) quantity,
  price
FROM `prices` p
CROSS JOIN `trans` t
GROUP BY price_date, price
-- ORDER BY price_date   
0 голосов
/ 04 октября 2018

Вы можете сделать:

select p.price_date,
       coalesce(t.quantity, lag(t.quantity ignore nulls) over (order by p.price_date)) as quantity
       p.price
from prices p join
     trans t
     on t.trans_date = p.price_date;

РЕДАКТИРОВАТЬ:

Это верно.IGNORE NULL s работает в некоторых контекстах, но не в других.Массивы обычно исправляются в BigQuery:

select price_date,
       (select quantity
        from unnest(quantities) quantity with OFFSET n
        where quantity is not null
        order by n desc
        LIMIT 1
       ) as quantity,
       price
from (select p.price_date,
             array_agg(t.quantity) over (order by p.price_date) as quantities,
             p.price
      from prices p LEFT join
           trans t
           on t.trans_date = p.price_date
    ) pp;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...