选择组中最后一个事务的唯一标识符--Bigquery

时间:2017-07-10 20:51:51

标签: sql google-bigquery

我正在尝试获取特定用户/帐户元组提交的最后一笔交易(用户可以拥有多个帐户)。这是我的方法

SELECT last_tx.user_id, last_tx.account_id, last_tx.last_tx_date, tx_all.transaction_id
FROM   [info.all_transactions] AS tx_all 
       JOIN (SELECT user_id, 
                    account_id, 
                    Max(transaction_date) as last_tx_date 
             FROM   info.all_transactions 
             GROUP  BY user_id, 
                       account_id) AS last_tx 
         ON tx_all.user_id = last_tx.user_id 
            AND tx_all.account_id = last_tx.account_id 
            AND tx_all.transaction_date = last_tx.last_tx_date

但我的结果是空的。主键是transaction_id

3 个答案:

答案 0 :(得分:1)

这对你有用吗?

#standardSQL
WITH data AS(
select '1' user_id, '1' account_id, '20170701' dt UNION ALL
select '1' user_id, '1' account_id, '20170702' dt UNION ALL
select '1' user_id, '2' account_id, '20170701' dt UNION ALL
select '2' user_id, '1' account_id, '20170701' dt UNION ALL
select '2' user_id, '1' account_id, '20170702' dt
)

SELECT
  *
FROM(
  SELECT
    user_id,
    account_id,
    FIRST_VALUE(dt) OVER(PARTITION BY user_id, account_id ORDER BY dt DESC) max_dt
  FROM data
  )
GROUP BY
user_id, account_id, max_dt

data模拟您的info.all_transactions

答案 1 :(得分:1)

我会这样做:

SELECT d.*
FROM (SELECT t.*,
             ROW_NUMBER() OVER (user_id, account_id ORDER BY transaction_date DESC) as seqnum
      FROM info.all_transactions t
     ) t
WHERE seqnum = 1;

这将返回行上的所有值。当然,您可以选择所需的列。

答案 2 :(得分:1)

以下是BigQuery Standard SQL

  
#standardSQL
SELECT
  user_id, 
  account_id, 
  transaction_date AS last_tx_date, 
  transaction_id
FROM(
  SELECT
    *,
    ROW_NUMBER() OVER(PARTITION BY user_id, account_id ORDER BY transaction_date DESC) = 1 AS last_transaction
  FROM `info.all_transactions`
  )
WHERE last_transaction

您可以使用一些虚拟数据进行测试,如下所示

#standardSQL
WITH `info.all_transactions` AS (
  SELECT '1' AS user_id, '1' AS account_id, '20170701' AS transaction_date, 1 AS transaction_id UNION ALL
  SELECT '1', '1', '20170702', 2 UNION ALL
  SELECT '1', '2', '20170701', 3 UNION ALL
  SELECT '2', '1', '20170701', 4 UNION ALL
  SELECT '2', '1', '20170702', 5 
)
SELECT
  user_id, 
  account_id, 
  transaction_date AS last_tx_date, 
  transaction_id
FROM(
  SELECT
    *,
    ROW_NUMBER() OVER(PARTITION BY user_id, account_id ORDER BY transaction_date DESC) = 1 AS last_transaction
  FROM `info.all_transactions`
  )
WHERE last_transaction
ORDER BY user_id, account_id 
  

更新版本以处理资源超出问题

#standardSQL
WITH `info.all_transactions` AS (
  SELECT '1' AS user_id, '1' AS account_id, '20170701' AS transaction_date, 1 AS transaction_id UNION ALL
  SELECT '1', '1', '20170702', 2 UNION ALL
  SELECT '1', '2', '20170701', 3 UNION ALL
  SELECT '2', '1', '20170701', 4 UNION ALL
  SELECT '2', '1', '20170702', 5 
)
SELECT row.* 
FROM (
  SELECT ARRAY_AGG(r ORDER BY transaction_date DESC LIMIT 1)[OFFSET(0)] AS row
  FROM `info.all_transactions` AS r
  GROUP BY user_id, account_id
)
ORDER BY user_id, account_id