【问题标题】:Update rows in SQL every 20 iterations每 20 次迭代更新 SQL 中的行
【发布时间】:2018-03-01 03:15:16
【问题描述】:

我在来自the NYC Yellow TaxiCab public dataset 的 Google BigQuery 中有一个包含约 100 万行的表。正如您从该链接中看到的那样,该模式没有主键。每行代表一次旅行/交易,但没有customer_id 字段。

我想添加一列 customer_id 并向其分配随机数,以便:

For rows 1-20, `customer_id` should be assigned `1`
For rows 21-40, `customer_id` should be assigned `2`
and so on..

换句话说,我希望表中的 20 行恰好(和任何)具有特定值 customer_id

【问题讨论】:

  • 如何对这些行进行排序?意思是,“第1行”是什么意思?请注意,在 SQL 世界中,行没有顺序,除非您给它们一个顺序。
  • 有没有办法将字段添加到表中,使其每 20 行后递增。
  • 但是为什么呢?了解用例可能会让我们找到解决问题的替代答案
  • 我想查看大约 100 万客户的聚合数据,每个客户有 20 行。所以我希望一个客户在表中有 20 笔交易
  • 为每个客户分配完全随机的行?它必须是 20,还是每个 id 可以得到大约 17~23 行?

标签: mysql sql google-bigquery


【解决方案1】:

为每一行分配一个随机 id,为每个 new_id 获取约 20 行的组:

#standardSQL
SELECT CAST(FLOOR(COUNT(*) OVER()/20*RAND()) AS INT64) new_id, *
FROM (
  SELECT login
  FROM `ghtorrent-bq.ght_2017_04_01.users`
  LIMIT 1000000
)

证明超过一百万行时生成了 50,000 个“customers_id”:

【讨论】:

    【解决方案2】:

    以下是 BigQuery 标准 SQL,每个 customer_id 正好生成 20 个条目

    #standardSQL
    SELECT DIV(ROW_NUMBER() OVER() - 1, 20) AS customer_id, *
    FROM `yourTable`
    -- ORDER BY customer_id
    

    您可以使用下面的虚拟数据来测试游戏

    #standardSQL
    WITH `yourTable` AS (
        SELECT login
        FROM `ghtorrent-bq.ght_2017_04_01.users`
        LIMIT 1000000
    )
    SELECT DIV(ROW_NUMBER() OVER() - 1, 20) AS customer_id, *
    FROM `yourTable`
    -- ORDER BY customer_id  
    

    此外 - 下面的查询显示了每个 customer_id 的计数分布

    #standardSQL
    WITH `yourTable` AS (
        SELECT login
        FROM `ghtorrent-bq.ght_2017_04_01.users`
        LIMIT 1000000
    )
    SELECT cnt, COUNT(1) AS distribution FROM (
      SELECT customer_id, COUNT(1) AS cnt FROM (
        SELECT *, DIV(ROW_NUMBER() OVER() - 1, 20) AS customer_id
        FROM `yourTable`
        ORDER BY customer_id
      )
      GROUP BY customer_id
    )
    GROUP BY cnt
    ORDER BY cnt   
    

    输出如下

    Row cnt distribution     
    --- --- ------------
    1    20        50000     
    

    【讨论】:

    • 我想到了这个,但是出于可扩展性的原因,我想避免使用ROW_NUMBER() OVER()(如果列中的数据过多,PARTITION 会导致失败)
    • 同意。 :o) 在任何情况下都不推荐使用 ROW_NUMBER() ,但在这种情况下 PO 提到了 I have a table with ~1 million rows 所以我认为他尝试是有意义的,因为它给出了他想要的精确分布(每个 id 20 个条目)
    • 谢谢大家。此外,有什么方法可以对大约 1000 万条记录执行此操作。 BigQuery 中断说资源超出。必须有办法分批做到这一点吗? 500000 个客户的 1000 万条记录(假设每个客户 20 行)。
    • @AkshayApte - 我刚刚尝试了我和 Felipe 的解决方案,当然两者都为 10M 工作,但在 Felipe 的回答中,每 500000 名客户的精确分布为 20 行,而钟形分布的分布有所不同。那么究竟是什么不适合你呢?请说清楚!我建议您提出新问题,发布您遇到的错误的确切最终查询,以便我们可以有效地提供帮助,而不仅仅是评论。
    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 2022-01-10
    • 2017-11-20
    • 2019-11-29
    • 1970-01-01
    • 2020-02-27
    • 1970-01-01
    相关资源
    最近更新 更多