繁体   English   中英

BigQuery:检索两列中唯一的行,否则检索第三列最大的行

[英]BigQuery: Retrieve rows that are unique across two columns, otherwise row with largest third column

我有一个BigQuery表my_table ,如下所示:

+---------+---------+-------+------------------+----------+--------+-----+--------+
| poll_id | user_id | count |    timestamp     | timezone | answer | age | gender |
+---------+---------+-------+------------------+----------+--------+-----+--------+
|       1 |       1 |     5 | 2019-08-06 11:00 |        1 | no     |  25 | male   |
|       1 |       1 |    10 | 2019-08-06 10:00 |        1 | no     |  25 | male   |
|       1 |       1 |    10 | 2019-08-06 10:30 |        1 | yes    |  25 | male   |
|       1 |       2 |    10 | 2019-08-06 11:00 |        1 | no     |  35 | male   |
|       1 |       2 |    20 | 2019-08-06 11:00 |        1 | no     |  35 | male   |
|       1 |       2 |    35 | 2019-08-06 11:00 |        1 | NULL   |  35 | male   |
|       2 |       1 |    10 | 2019-08-06 10:35 |        1 | no     |  25 | male   |
|       3 |       1 |    10 | 2019-08-06 10:35 |        1 | NULL   |  25 | male   |
+---------+---------+-------+------------------+----------+--------+-----+--------+

我想检索满足以下要求的行:

  • 如果该行具有 poll_iduser_id的唯一组合,则在answer具有非NULL值的情况下包括该行
  • 如果该行没有 poll_id和user_id的唯一组合:
    • answer列中包含count最大但非NULL的行
      • 如果有两行具有相同的count (且answer为非NULL),则包括timestamp最大的行

我还希望能够将搜索限制为特定的日期和时区,例如日期为2019-08-06且时区为1,并且我不想在user_id检索值为NULL的行。

到目前为止,我已经尝试了以下标准SQL语句:

  SELECT
    t1.poll_id,
    t1.user_id,
    t1.count,
    t1.timestamp,
    t1.timezone,
    t1.answer,
    t1.age,
    t1.gender,
  FROM
    `my_table` t1
  LEFT JOIN
    `my_table` t2
  ON
    t1.poll_id = t2.poll_id
    AND t1.user_id = t2.user_id
    AND t1.count < t2.count
    AND t2.answer IS NOT NULL
    AND DATE(t2.timestamp, "+1:00") = "2019-08-06"
  WHERE
    t1.user_id IS NOT NULL
    AND t1.answer IS NOT NULL
    AND DATE(t1.timestamp, "+1:00") = "2019-08-06"
    AND t1.timezone = 1   
    AND t2.count IS NULL

所示表的预期结果是:

+---------+---------+-------+------------------+----------+--------+-----+--------+
| poll_id | user_id | count |    timestamp     | timezone | answer | age | gender |
+---------+---------+-------+------------------+----------+--------+-----+--------+
|       1 |       1 |    10 | 2019-08-06 10:30 |        1 | yes    |  25 | male   | // count = 10 and largest timestamp
|       1 |       2 |    20 | 2019-08-06 11:00 |        1 | no     |  35 | male   | // count = 20 (the 35 row had NULL in 'answer')
|       2 |       1 |    10 | 2019-08-06 10:35 |        1 | no     |  25 | male   | // unique 'poll_id', 'user_id' combination
+---------+---------+-------+------------------+----------+--------+-----+--------+

但是,似乎有两个问题:

  1. 如果有多个具有相同(最大) count数值的行,则将检索所有这些行。 这意味着在此示例中将同时检索第2行和第3行。
  2. 如果poll_iduser_id组合恰好有两行,即使它们具有不同的count数值,也不会检索到这两行。

至少看起来是这样。 我很难跟踪问题,当然,还要找出正确的查询。

任何帮助,将不胜感激。

对于这种类型的查询,通常使用row_number() 我认为这符合您的描述:

select t.*
from (select t.*,
             row_number() over (partition by poll_id, user_id order by count desc, timestamp desc) as seqnum
      from my_table t
      where answer is not nll
     ) t
where seqnum = 1;

以下是BigQuery标准SQL

#standardSQL
SELECT * EXCEPT(pos) 
FROM (
  SELECT *, 
    ROW_NUMBER() OVER(PARTITION BY poll_id, user_id ORDER BY count DESC, timestamp DESC) AS pos
  FROM `project.dataset.table`
  WHERE NOT answer IS NULL
  AND NOT user_id IS NULL
  AND timezone = 1
  AND SUBSTR(timestamp, 1, 10) = '2019-08-06'
)
WHERE pos = 1   

如果适用于您问题中的样本数据-结果为

Row poll_id user_id count   timestamp           timezone    answer  age gender   
1   1       1       10      2019-08-06 10:30    1           yes     25  male     
2   1       2       20      2019-08-06 11:00    1           no      35  male     
3   2       1       10      2019-08-06 10:35    1           no      25  male     

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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