我想请人帮助解决一个困扰我两天的问题.

我有这样的"结果"表:

result_id competition_id competitor_id competitor_ranking
1 1 1 0.1
2 1 2 0.4
3 1 3 0.2
4 1 4 0.3
5 2 1 0.4
6 2 2 0.1
7 2 3 0.2
8 2 5 0.3
9 3 3 0.1
10 3 4 0.4
11 3 5 0.2
12 3 6 0.3

从"结果"表中,我想得到一个包括罚分(+1.0)的竞争者分组排名,如下所示:

competitor_id competitions rankings ranking_with_penalties
1 1; 2; M 0.1; 0.4 0.1; 0.4; +1.0
2 1; 2; M 0.4; 0.1 0.4; 0.1; +1.0
3 1; 2; 3 0.2; 0.2; 0.1 0.2; 0.2; 0.1
4 1; M; 3 0.3; 0.4 0.3; +1.0; 0.4
5 M; 2; 3 0.3; 0.2 +1.0; 0.3; 0.2
6 3; M; M; 0.3 0.3; +1.0; +1.0

我知道group_concat函数是一个聚合函数,它将所有非空值串联在一个列中.我知道这项任务很琐碎.但我解决不了.

CREATE TABLE results (
  result_id INTEGER PRIMARY KEY, 
  competition_id INTEGER,
  competitor_id INTEGER,
  competitor_ranking 
);

INSERT INTO results(competition_id, competitor_id, competitor_ranking) VALUES 
  (1, 1, 0.1), (1, 2, 0.4), (1, 3, 0.2), (1, 4, 0.3),
  (2, 1, 0.4), (2, 2, 0.1), (2, 3, 0.2), (2, 5, 0.3),
  (3, 3, 0.1), (3, 4, 0.4), (3, 5, 0.2), (3, 6, 0.3)
;

SELECT
  competitor_id,
  group_concat(coalesce(competition_id, NULL), '; ') AS competitions,
  group_concat(coalesce(competitor_ranking, NULL), '; ') AS rankings,
  group_concat(coalesce(NULLIF(competitor_ranking, NULL), '+1.0'), '; ') AS ranking_with_penalties
FROM results
GROUP BY competitor_id;
  • M是一个符号,意味着一个竞争者错过了一场比赛,并遵循排名与处罚逻辑.我需要获得参赛者分组样本中错过的比赛,并将其替换为罚分(+1.0)以计算最终排名.一个参赛者应该参观的比赛.
    • added the above from the comments

我期待着任何帮助.

推荐答案

我相信下面的方法会产生你想要的结果

  • i.e. enter image description here
    • 注意,参赛者6在比赛3中并不符合您的预期结果(但可能应该是上面的结果,即M(comp1); M(comp2); 3(comp3)根据之前的结果)
    • 排名(+1.0位)也是如此

使用:

WITH 
    cte_comp_competitor_matrix AS (
        SELECT DISTINCT results.competition_id,c2.competitor_id FROM results JOIN results AS c2 ON 1
    ),
    cte_stage2 AS (
        SELECT competitor_id,competition_id,
             CASE cccm.competitor_id IN(SELECT competitor_id FROM results WHERE competition_id = cccm.competition_id) 
                WHEN 1 THEN competition_id ELSE 'M' END
            AS matched
        FROM cte_comp_competitor_matrix AS cccm ORDER BY competitor_id
    ),
    cte_stage3 AS (
        SELECT *,
            coalesce(
                (
                    SELECT competitor_ranking 
                    FROM results 
                    WHERE cte_stage2.competitor_id = results.competitor_id 
                        AND cte_stage2.competition_id = results.competition_id
                ),
                '+1.0'
            ) AS competitor_ranking
        FROM cte_stage2
    )
SELECT 
    competitor_id,
    group_concat(matched,';') AS competitions,
    group_concat(competitor_ranking,';') AS rankings
FROM cte_stage3
GROUP BY competitor_id
;
  • cte_comp_competition_matrix检索每个竞争对手/竞争对手组合

    • enter image description here
  • cte_stage2 (for want of a better name) applies the M (missing) ` enter image description here

  • cte_stage3(更好的名字??)应用排名(从而有效地为错过的比赛添加原始+额外的行)

    • enter image description here
  • CTE =公共表表达式,这是一个临时表,持续执行期间(可以看到,您可以有多个CTE).它们已被用来逐步达到预期结果.

    • 他们没有故意简化为更短的代码,希望使他们更容易理解,

Sql相关问答推荐

获取每个帖子的匹配关键字列表

当我们加入两个表时,我们可以省略GROUP BY中的列名吗?

使用SQL旋转表的列(Snowflake)

Oracle SQL-将结果列在单行中

按每天的最大值分组

从原始表列中经过JSON字符串化的对象数组构建视图

如何嵌套两条SQL语句

SQL Select 最小优先级

从字符串中删除";1、";和";2,";,而不删除";11、";和";12、";

Redshift PL/pgSQL循环中的参数化列名

根据Rails活动记录中时间戳/日期时间的时间部分从PostgreSQL中提取记录

将二维数组的第一个和第二个元素取消嵌套到两个一维数组中

根据时间值提取记录

group by 并根据同表中其他列的某些条件获取 group by 中的某一列值

JSON对象查询SQL服务器

SQL 多个不满足的条件失败

如何在插入时将字符串'03-January-2023'转换为日期时间

在 MS Access VBA 中,如何测量显示查询的时间?

如何根据与 BigQuery 中另一个表的匹配更新一个表中的列?

基于源表的 SQL INSERT、UPDATE 和 DELETE