【问题标题】:Counting current and longest streaks of a given value计算给定值的当前和最长条纹
【发布时间】:2020-03-21 17:04:10
【问题描述】:

我有 2 个表 Person(ID、NAME、CLAN_ID)和 DailyScore(PERSON_ID、CLAN_ID、DAY_NUMBER、SCORE)。

SCORE 可以取值“A”、“B”、“C”或“-”(“-”表示不存在)。

对于给定的 CLAN_ID,我需要进行 2 个单独的查询:

  • 每个人的给定分数(例如 A)的当前连胜记录和人的姓名,按连胜长度 DESC 排序
  • 每个人的给定分数(例如 A)的最长连胜记录和人的姓名,按连胜长度 DESC 排序

一个重要的限制是忽略“-”分数,因为它们代表缺席,而不是真实分数。

示例数据:

桌人:

_ID  NAME    CLAN_ID
1    John    11
2    Alice   11
3    Bob     12
4    Sara    12

表 DailyScore:

PERSON_ID   CLAN_ID   DAY_NUMBER   SCORE
1           11        1            A
1           11        2            A
1           11        3            A
1           11        4            C
1           11        5            A
2           11        1            B
2           11        2            C
2           11        3            B
2           11        4            A
2           11        5            A
3           12        1            A
3           12        2            A
3           12        3            A
3           12        4            A
3           12        5            B
4           12        1            C
4           12        2            B
4           12        3            C
4           12        4            A
4           12        5            -

所需结果示例 1(CLAN_ID=11,SCORE=A):

当前连续:

Alice   2
John    1

最长的连胜纪录:

John    3
Alice   2

期望结果示例 2(CLAN_ID=12,SCORE=A):

当前连续:

Sara    1*
Bob     0

*因为“-”被忽略,Sara 的当前连续得分为 1 A

最长的连胜纪录:

Bob     4
Sara    1

编辑:

如果有帮助,下面是 SQL Fiddle 中的示例:http://sqlfiddle.com/#!7/2ed69/2

【问题讨论】:

  • 第二个查询是典型的“Gaps & Islands”问题。这需要 SQL 窗口框架来解决。 SQLite 是否实现了窗口框架? ——我认为确实...
  • @TheImpaler 只要您使用的是 3.25 或更新版本,它就可以。
  • 这是针对最低 API 26 的 Android 应用程序,根据 developer.android.com,它使用 SQLite 版本 3.18

标签: sql sqlite


【解决方案1】:

第一个查询可以是:

select
  id, name, max(s) as streak
from (
  select
    p.id,
    p.name,
    count(*) over(partition by p.id order by s.day_number desc) as c,
    sum(case when s.score = 'A' then 1 else 0 end)
      over(partition by p.id order by s.day_number desc) as s
  from person p
  join dailyscore s on s.person_id = p.id
) x
where c = s
group by id, name

【讨论】:

  • 谢谢,但它似乎忽略了“缺席”约束。也许是因为我是在第一次发布后添加的。
猜你喜欢
  • 1970-01-01
  • 2019-08-24
  • 2015-10-08
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多