【发布时间】:2021-02-07 22:05:58
【问题描述】:
任务:选择至少连续参加2场比赛的运动员(2场比赛接连进行;1-2-3-4-5:2&4或1&3&5不行,1&2可以,1&2&3可以, 1&2 和 4&5 都可以)。 问题:找到最好的方法(更快,更少的资源)
工作台:
每个比赛 ID 都有一个 hold_date。
每个sportsman_id 每个competition_id 只有一个结果。
这适用于结果表中的 25 行:
SELECT DISTINCT sportsman_id, sportsman_name, rank, year_of_birth, personal_record, country
FROM
(
SELECT sportsman_id, hold_date,
LAG (comp_order, 1) OVER (PARTITION BY sportsman_id ORDER BY sportsman_id) prev_comp_number
, comp_order
FROM result
INNER JOIN
(
SELECT hold_date, ROW_NUMBER() OVER (ORDER BY hold_date) AS comp_order
FROM
(
SELECT DISTINCT hold_date
FROM result
)
) USING (hold_date)
ORDER BY sportsman_id, comp_order
)
INNER JOIN sportsman USING (sportsman_id)
WHERE comp_order-prev_comp_number=1
;
使用 cmets 的代码截图:
样本数据:
上面代码的结果(=期望的结果)
假设有数百万行(数以千计的比赛和数以千计的运动员)。我的代码有多可靠?
如果sportsman_id 只出现一次,我认为通过排除行来减少行数(如果运动员只参加了一场比赛(获得结果),他显然不能成为那个人)。 像这样的东西:(还没有实现(不知道如何或最有可能何时/何地))
SELECT re.hold_date, r.sportsman_id
FROM result r
INNER JOIN result re ON (re.sportsman_id=r.sportsman_id)
GROUP BY r.sportsman_id, re.hold_date
HAVING COUNT(r.sportsman_id) > 1
;
那么,我猜我用 LAG 只会将现有列加倍,这还不错?
使用 PLSQL 有更简单的方法吗?或者有一个函数可以完成我的代码的某些部分?
【问题讨论】:
-
样本数据和期望的结果会有很大帮助。
-
添加为截图
-
您的数据模型显示一场比赛可以跨越数天(因此日期在结果表中,否则会在比赛表中)。这是否也意味着两场比赛可以重叠?我能在 9 月 5 日和 6 日找到一场比赛,在 9 月 4 日和 7 日找到另一场比赛吗?如果是这样,该怎么办?
-
请edit您的问题以文本形式包含示例数据、注释代码和所需结果(对于代码,最好是我们可以复制/粘贴的 DDL/DML 语句)。
-
@ThorstenKettner 如前所述:每个 Competition_id 都有一个 hold_date。没有重叠;所以实际上 hold_date 是独一无二的。
标签: sql oracle subquery window-functions gaps-and-islands