在 SQL 中为每个类别查询不同数量的记录
Posted
技术标签:
【中文标题】在 SQL 中为每个类别查询不同数量的记录【英文标题】:Query different number of records for each category in SQL 【发布时间】:2018-03-15 19:52:51 【问题描述】:我有一个如下所示的表格:
col1 | col2 | col3 | col4
A | 1 | 2 | 4
A | 2 | 5 | 3
A | 5 | 1 | 6
B | 3 | 1 | 2
B | 4 | 4 | 4
我有另一个表,其中记录是唯一的,如下所示:
col1 | col2
A | 2
B | 1
我想以这样一种方式查询Table 1
,即根据Table 2
中类别的值,仅过滤掉Table 1
中每个类别的n
记录数。
基于Table 2
,我需要为A
提取2 条记录,为B
提取1 条记录。我需要生成的查询表如下所示:
col1 | col2 | col3 | col4
A | 2 | 5 | 3
A | 1 | 2 | 4
B | 3 | 1 | 2
记录的选择是根据col4
升序排列的。我目前正在尝试在 BigQuery 上执行此操作。
【问题讨论】:
【参考方案1】:您可以使用row_number()
和join
:
select t1.col1, t1.col2, t1.col3, t1.col4
from (select t1.*, row_number() over (partition by col1 order by col4) as seqnum
from table1 t1
) t1 join
table2 t2
on t2.col1 = t1.col1 and t1.seqnum <= t2.col2
order by t1.col1, t1.col4;
【讨论】:
【参考方案2】:以下是 BigQuery 标准 SQL
#standardSQL
SELECT t.*
FROM (
SELECT ARRAY_AGG(t1 ORDER BY t1.col4) arr, MIN(t2.col2) cnt
FROM table1 t1 JOIN table2 t2 ON t1.col1 = t2.col1
GROUP BY t1.col1
), UNNEST(arr) t WITH OFFSET num
WHERE num < cnt
您可以使用您问题中的虚拟数据来测试/玩它,如下所示
#standardSQL
WITH `table1` AS (
SELECT 'A' col1, 1 col2, 2 col3, 4 col4 UNION ALL
SELECT 'A', 2, 5, 3 UNION ALL
SELECT 'A', 5, 1, 6 UNION ALL
SELECT 'B', 3, 1, 2 UNION ALL
SELECT 'B', 4, 4, 4
), `table2` AS (
SELECT 'A' col1, 2 col2 UNION ALL
SELECT 'B', 1
)
SELECT t.*
FROM (
SELECT ARRAY_AGG(t1 ORDER BY t1.col4) arr, MIN(t2.col2) cnt
FROM table1 t1 JOIN table2 t2 ON t1.col1 = t2.col1
GROUP BY t1.col1
), UNNEST(arr) t WITH OFFSET num
WHERE num < cnt
输出为
Row col1 col2 col3 col4
1 A 2 5 3
2 A 1 2 4
3 B 3 1 2
【讨论】:
更新了答案,因为我意识到我使用 t1.col2 进行排序,但应该是 t1.col4 :o) 明白了 :) 感谢您的澄清!以上是关于在 SQL 中为每个类别查询不同数量的记录的主要内容,如果未能解决你的问题,请参考以下文章