Запрос на получение ежедневных отрицательных остатков на счетах по городам - PullRequest
0 голосов
/ 15 марта 2019

У меня есть список остатков на счетах с течением времени.Схема выглядит следующим образом:

+-------------+---------+---------+----------------------+
| customer_id | city_id |  value  |  timestamp           |
+-------------+---------+---------+----------------------+
| 1           | 1       |  -500   | 2019-02-12T00:00:00  |
| 2           | 1       |  -200   | 2019-02-12T00:00:00  |
| 3           | 2       |  200    | 2019-02-10T00:00:00  |
| 4           | 1       |  -10    | 2019-02-09T00:00:00  |
+-------------+ --------+---------+----------------------+

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

+---------+---------+--------------+
| city_id |  value  |   timestamp  |
+---------+---------+--------------+
| 1       | -500    |  2019-02-12  |
| 1       | -200    |  2019-02-10  |
| 1       | -10     |  2019-02-09  |
+ --------+---------+--------------+

ЧтоЯ пробовал:

SELECT city_id, FORMAT_TIMESTAMP("%Y-%m-%d", TIMESTAMP(timestamp)) as date,
  SUM(value) OVER (PARTITION BY city_id ORDER BY FORMAT_TIMESTAMP("%Y-%m-%d", TIMESTAMP(timestamp))) negative_account_balance 
FROM `account_balances`
WHERE value < 0

Однако это дает мне странные значения баланса счета, такие как -5.985856421224E10.Есть идеи почему?Кроме того, запрос генерирует записи для одного и того же города и одного и того же дня несколько раз.Я ожидаю, что он вернет один и тот же город только один раз за тот же день.

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT city_id, account_balance, `date` FROM (
  SELECT city_id, `date`, 
    SUM(value) OVER(PARTITION BY city_id ORDER BY `date`) account_balance 
  FROM (
    SELECT city_id, DATE(TIMESTAMP(t.timestamp)) AS `date`, SUM(value) value
    FROM `project.dataset.account_balances` t
    GROUP BY city_id, `date` )
)
WHERE account_balance< 0   

Вы можете проверить, поиграть с выше, используя пример / фиктивные данные, как в примере ниже

#standardSQL
WITH `project.dataset.account_balances` AS (
  SELECT 1 customer_id, 1 city_id, -500 value, '2019-02-12T00:00:00' `timestamp` UNION ALL
  SELECT 2, 1, -200, '2019-02-12T00:00:00' UNION ALL
  SELECT 5, 1, 100, '2019-02-13T00:00:00' UNION ALL
  SELECT 3, 2, 200, '2019-02-10T00:00:00' UNION ALL
  SELECT 4, 1, -10, '2019-02-09T00:00:00' 
)
SELECT city_id, account_balance, `date` FROM (
  SELECT city_id, `date`, 
    SUM(value) OVER(PARTITION BY city_id ORDER BY `date`) account_balance 
  FROM (
    SELECT city_id, DATE(TIMESTAMP(t.timestamp)) AS `date`, SUM(value) value
    FROM `project.dataset.account_balances` t
    GROUP BY city_id, `date` )
)
WHERE account_balance< 0   

, который дает результат ниже

Row city_id account_balance date     
1   1       -10             2019-02-09   
2   1       -710            2019-02-12   
3   1       -610            2019-02-13   
1 голос
/ 15 марта 2019

Я выбрал более простой подход и использовал этот sql (Кстати, когда я попробовал ваш исходный запрос, я получил результат, который кажется нормальным)

SELECT city_id, FORMAT_TIMESTAMP("%Y-%m-%d", TIMESTAMP(timestamp)) as date,
  SUM(value) as value
FROM `account_balances`
GROUP BY city_id, timestamp
HAVING value < 0

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

WITH account_balances as (
SELECT 1 AS customer_id, 1 as city_id, -500 as value, '2019-02-12 00:00:00' as timestamp UNION ALL
SELECT 2 AS customer_id, 1 as city_id, -200 as value, '2019-02-12 00:00:00' as timestamp UNION ALL
SELECT 3 AS customer_id, 2 as city_id, 200 as value, '2019-02-10 00:00:00' as timestamp UNION ALL
SELECT 4 AS customer_id, 1 as city_id, -10 as value, '2019-02-09 00:00:00' as timestamp
)

SELECT city_id, FORMAT_TIMESTAMP("%Y-%m-%d", TIMESTAMP(timestamp)) as date,
  SUM(value) as value
FROM `account_balances`
GROUP BY city_id, timestamp
HAVING value < 0

Это результат:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...