简体   繁体   中英

Select value ordered by another value in same table without sub-query

I am using SQL on GBQ.

I have a table with the following columns:

titlenum title ID
1 H:A:F 1
2 R:V:G 1
1 v234 2
2 B:N:E 2
3 R:V:G 2

I wrote a query that selects for each ID : the first title (ordered by titlenum ).

SELECT MAX(CASE WHEN  CAST(titlenum AS INT64 ) = 1 THEN title  END)  AS first_title
FROM `table`
GROUP BY ID

This returns the following result:

titlenum title ID
1 H:A:F 1
1 v234 2

PS: This SELECT query is a part of a bigger one, that selects a lot more columns.

I need to add another condition to my query: I want to select the title with the least value for titlenum that also has at least one ":" in its value.

So ideally I want this result:

titlenum title ID
1 H:A:F 1
2 B:N:E 2

I could do a sub-query, and then use the column first_title in the original query:

SELECT MIN(title) as first_title, ID      
FROM `table` 
WHERE title like '%:%'
GROUP BY ID

But is there a "better" way to do it? Can I use CASE WHEN instead of a sub-query? The original query is already too large and I want to avoid adding another sub-query to it.

In BigQuery, one method is aggregation:

select (array_agg(t order by titlenum limit 1))
from `table` t 
group by id;

This returns the entire row. You could just select the title if that is what you really want:

select id, (array_agg(t.title order by titlenum limit 1))[ordinal(1)] as title

[ordinal(1)].* from table t group by id;

However, based on your numbering, don't you just want filtering:

select t.*
from `table` t 
where titlenum = 1;

Usually ARRAY_AGG is used for such cases in BigQuery:

with `table` as (
  select 1 as titlenum, 'H:A:F' as title, 1 as id union all
  select 2, 'R:V:G', 1 union all
  select 1, 'v234', 2 union all
  select 2, 'B:N:E', 2 union all
  select 3, 'R:V:G', 2
)
select ARRAY_AGG(STRUCT(titlenum, title) ORDER BY titlenum)[OFFSET(0)].*, id
from `table`
where title like '%:%'
group by id

在此处输入图像描述

Consider below

select as value array_agg(t order by titlenum)[offset(0)]
from `project.dataset.table` t
where regexp_contains(title, ':')
group by id    

when applied to sample data in your question - output is

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM