Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to returning BigQuery table rows with a max value

I've a simple bigquery table with 3 columns (and some example data) below:

|---------------------|------------------|------------|
|      Name           |     Time         |  Value     |
|---------------------|------------------|------------|
|          a          |         1        |   x        |
|---------------------|------------------|------------|
|          a          |         2        |   y        |
|---------------------|------------------|------------|
|          a          |         3        |   z        |
|---------------------|------------------|------------|
|          b          |         1        |   x        |
|---------------------|------------------|------------|
|          b          |         4        |   y        |
|---------------------|------------------|------------|

For each name, I'd like to return the value with the max time.

For the above table the 3rd and 5th row should be returned, e.g.,

|---------------------|------------------|------------|
|      Name           |     Time         |  Value     |
|---------------------|------------------|------------|
|          a          |         3        |   z        |
|---------------------|------------------|------------|
|          b          |         4        |   y        |
|---------------------|------------------|------------|

It is roughly like: (1) first group by Name, (2) find out the max time in each group, (3) identify the row with the max time.

Seems for (1) and (2), we can use group by + max(), but i'm not sure how to achieve the (3) step.

Anyone has ideas of what's the best query I can write to achieve this purpose.

Thanks a lot.

like image 299
SZZ Avatar asked Mar 23 '26 18:03

SZZ


2 Answers

ROW_NUMBER is one way to go here:

SELECT Name, Time, Value
FROM
(
    SELECT *, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Time DESC) rn
    FROM yourTable
) t
WHERE rn = 1;

Using QUALIFY we can try:

SELECT Name, Time, Value
FROM yourTable
WHERE TRUE
QUALIFY ROW_NUMBER() OVER (PARTITION BY Name ORDER BY Time DESC) = 1;
like image 183
Tim Biegeleisen Avatar answered Mar 26 '26 13:03

Tim Biegeleisen


Below is for BigQuery Standard SQL

#standardSQL
SELECT AS VALUE ARRAY_AGG(t ORDER BY time DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.table` t 
GROUP BY name

if to apply to sample data from your question as in below example

#standardSQL
WITH `project.dataset.table` AS (
  SELECT 'a' name, 1 time, 'x' value UNION ALL
  SELECT 'a', 2, 'y' UNION ALL
  SELECT 'a', 3, 'z' UNION ALL
  SELECT 'b', 1, 'x' UNION ALL
  SELECT 'b', 4, 'y' 
)
SELECT AS VALUE ARRAY_AGG(t ORDER BY time DESC LIMIT 1)[OFFSET(0)]
FROM `project.dataset.table` t 
GROUP BY name   

result is

Row name    time    value    
1   a       3       z    
2   b       4       y   
like image 28
Mikhail Berlyant Avatar answered Mar 26 '26 14:03

Mikhail Berlyant



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!