30

有没有办法获取 BigQuery 中每条记录的行号?(从规范来看,我没有看到任何关于它的信息)有一个 NTH() 函数,但这适用于重复字段。

在 BigQuery 中有一些不需要行号的场景,例如使用 TOP() 或 LIMIT 函数。但是,我需要它来模拟一些分析函数,例如累积 sum()。为此,我需要用序号标识每条记录。有什么解决方法吗?

在此先感谢您的帮助!

狮子座

4

5 回答 5

56

2018 年更新:如果您想要的只是每一行的唯一 ID

#standardSQL
SELECT GENERATE_UUID() uuid
 , * 
FROM table

2018 #standardSQL 解决方案:

SELECT
  ROW_NUMBER() OVER() row_number, contributor_username,
  count
FROM (
  SELECT contributor_username, COUNT(*) count
  FROM `publicdata.samples.wikipedia`
  GROUP BY contributor_username
  ORDER BY COUNT DESC
  LIMIT 5)

但是“查询执行期间资源超出:无法在分配的内存中执行查询。OVER() 运算符使用了太多内存..”怎么办?

好的,让我们重现该错误:

SELECT *, ROW_NUMBER() OVER() 
FROM `publicdata.samples.natality` 

是的 - 发生这种情况是因为 OVER() 需要将所有数据放入一个 VM 中 - 您可以使用 PARTITION 解决这个问题:

SELECT *, ROW_NUMBER() OVER(PARTITION BY year, month) rn 
FROM `publicdata.samples.natality` 

“但是现在很多行都有相同的行号,而我想要的只是每行都有一个不同的 id”

好的好的。让我们使用分区为每一行指定一个行号,然后将该行号与分区字段结合起来,以获得每行的唯一 ID:

SELECT *
  , FORMAT('%i-%i-%i', year, month, ROW_NUMBER() OVER(PARTITION BY year, month)) id
FROM `publicdata.samples.natality` 

在此处输入图像描述


2013 年的原始解决方案:

好消息:BigQuery 现在有一个 row_number 函数。

简单的例子:

SELECT [field], ROW_NUMBER() OVER()
FROM [table]
GROUP BY [field]

更复杂的工作示例:

SELECT
  ROW_NUMBER() OVER() row_number,
  contributor_username,
  count,
FROM (
  SELECT contributor_username, COUNT(*) count,
  FROM [publicdata:samples.wikipedia]
  GROUP BY contributor_username
  ORDER BY COUNT DESC
  LIMIT 5)
于 2013-05-14T04:10:43.037 回答
3

另一个HACK将遵循以下原则:

SELECT *
FROM UNNEST(ARRAY(
    SELECT myColumn FROM myTable
)) AS myValue WITH OFFSET off

这为您提供了一个包含 2 列的结果集:myValueoff.

这样做的好处是您还可以offWHERE子句中使用创建非确定性LIMIT,例如WHERE off < (SELECT SUM(amount) FROM mySecondTable)

请注意,我不认为这是处理大量数据的可行替代方案。但它可能适合您的用例。

于 2018-11-28T09:02:20.510 回答
0

我想也许我可以通过在 <= 上将表连接到自身然后对结果执行 count(*) 来解决缺少 ROW_NUMBER() 函数的问题(有时在 MySQL 中就是这样做的)。事实证明,BigQuery 仅支持直接连接“=”。

再次被挫败。我认为这在 BQ 是不可能的。

于 2013-02-05T20:55:05.863 回答
0

我们不公开行标识符。您可以在导入数据时简单地将其添加到数据中吗?

于 2012-06-15T20:59:36.613 回答
0

我最近遇到了这个问题,但我的用例需要从头到尾的连续行号。可能不理想,但将其留在这里以防它可以帮助某人。

我为每个分区使用一个带有偏移量的指南表,以添加到它的所有行中。此偏移量是它之前所有分区中的行数之和。

select offset+ROW_NUMBER() OVER(PARTITION BY partitionDate) rowId
from `sample.example` input
left join
      (select partitions.partitionDate, partitions.count, SUM(duplicate.count)-partitions.count as offset
       from (
           select date(_PARTITIONTIME) partitionDate,COUNT(1) count 
           FROM `sample.example` 
           where date(_PARTITIONTIME) >= "2020-01-01" 
           group by _PARTITIONTIME) partitions
      inner join (
           select date(_PARTITIONTIME) partitionDate,COUNT(1) count 
           FROM `sample.example`
           where date(_PARTITIONTIME) >= "2020-01-01" 
           group by _PARTITIONTIME) duplicate 
      on partitions.partitionDate >= duplicate.partitionDate
      group by partitions.partitionDate, partitions.count
      order by partitions.partitionDate) guide
on date(_PARTITIONTIME) = guide.partitionDate
where date(_PARTITIONTIME) >= "2020-01-01" 
order by partitionDate
于 2020-05-09T06:31:23.153 回答