当前位置:首页>java>SQL编程大赛第5名周仟荣:用 PostgreSQL 位运算解决数独问题,碾压常规解法!

SQL编程大赛第5名周仟荣:用 PostgreSQL 位运算解决数独问题,碾压常规解法!

  • 2026-01-23 05:54:41
SQL编程大赛第5名周仟荣:用 PostgreSQL 位运算解决数独问题,碾压常规解法!
数据库编程大赛:用一条 SQL 解数独问题
2025 NineData 第三届数据库编程大赛圆满举办!本次大赛由 NineData 和云数据库技术社区主办,并联合佰晟智算、达梦数据、 ITPUB、CSDN、IFclub、开源中国、DataFun、墨天轮等技术社区共同举办。本届大赛延续 "一条 SQL" 的核心挑战,设置题目为「用一条 SQL」解数独问题查看赛题详情
以下是本次决赛第 5 名选手,周仟荣的参赛介绍:
第5名
周仟荣
参赛选手:周仟荣
选手简介:数据分析师,来自东风日产数据服务有限公司
参赛数据库:PostgreSQL
性能评测1 万级数据代码性能评测 15.933 
综合得分82.3
以下是周仟荣选手的代码说明思路简介:

算法流程概览

  • 数组高效构建棋盘

  • 位掩码进行高效数据压缩和运算

  • 分流策略:

    1.简单题:具有唯一候选,快速扫描,不回溯

    2.剩余难题:MRV策略进行剪枝

  • 合并输出

  • FILTER、DISTINCT ON 等PostgreSQL特有语法的应用对性能有一定提升

  • 延迟物化、内存压缩(Smallint)等优化对性能有提升

核心算法解析-位掩码

清洗、坐标构建

使用正则进行格式清洗,将待填空格替换为0

使用数组进行棋盘坐标构建

--示例生成中间表create  table dwd_sudoku_step1 asWITH RECURSIVE-- 1. 数据源 & 强壮解析 (Robust Parsing)src AS (    SELECT        id,        puzzle,        -- 【关键修复】:        -- 1. regexp_replace: 先暴力剔除所有非数字、非点、非问号的字符 (包括空格、换行、制表符等)        -- 2. translate: 再将 '.' 和 '?' 统一转为 '0'        -- 3. 结果: 得到纯净的 81 位数字字符串,绝对不会错位        string_to_array(            translate(                regexp_replace(puzzle, '[^0-9.?]''''g'),                '.?''00'            ),            NULL        )::smallint[] AS board    FROM sudoku9_9 --题面)-- 2. 棋盘单元格坐标构建    SELECT        id, val, i,   --id,原值,81位字符串序号        (i-1)/9 as r,   --行        (i-1)%9 as c,   --列        ((i-1)/27)*3 + ((i-1)%9)/3 as bx  --宫    FROM src, unnest(board) WITH ORDINALITY as t(val, i)  --数组展开为行;where id=1;

位图运算-1-二进制独热位掩码

数字1~9位掩码:

利用 二进制独热位掩码 (Binary One-hot Bitmask) 技术,将棋盘 1-9 的十进制数值映射为特定的二进制位状态。

示例,第1行的已有数字 1、2、5、6、7 进行OR (|) 运算转为 二进制掩码 001110011再转为10进制 115

--以第一行为例--棋盘数字转为二进制掩码SELECT    a.id           AS "ID",            --id    a.r + 1        AS "Row",          -- 行号    a.val         AS "Digit",         -- 数独数字    (1 << (a.val-1))          AS "Decimal", -- 十进制位状态    (1 << (a.val-1))::bit(9)  AS "Binary"   -- 二进制位状态FROM dwd_sudoku_step1 aWHERE a.id=1 AND a.val>0 AND a.r=0;--掩码 OR (|) 运算聚合SELECT    a.id           AS "ID",            --id    a.r + 1        AS "Row",          -- 行号    array_agg(a.val)        AS "Digit",         -- 数独数字    bit_or(1 << (a.val-1))          AS "Decimal", -- 十进制位状态    bit_or(1 << (a.val-1))::bit(9)  AS "Binary"   -- 二进制位状态FROM dwd_sudoku_step1 aWHERE a.id=1 AND a.val>0 AND a.r=0group by 1,2;

位图运算-2-行、列、宫已有数字掩码(黑名单)

以上示例拓展到行、列、宫,使用位掩码 bit_or (按位或) ,将每一行、列、宫中已有的数字记录在一个二进制数中,极大提升运算性能;

--Smallint更轻量计算速度更快

-- 3. 批量初始化掩码 (Filter 聚合)masks_calc AS (----使用“位掩码”技术。通过位运算(Bitwise OR)将每一行、列、宫中已有的数字记录在一个二进制数中    SELECT id, array_agg(COALESCE(m, 0)::smallint ORDER BY idx) as ms    FROM (        SELECT id, r+1 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, r        UNION ALL        SELECT id, c+10 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, c        UNION ALL        SELECT id, bx+19 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, bx    ) t    GROUP BY id),
结果为长度9*3=27的数组,分别表示行、列、宫各9组已有数字的掩码

位图运算-3-核心算法 — 位掩码与集合论 (Bitwise Set Theory)

Candidate=All(511)∩Not(Used)

即:

511& (Row∣Col∣Box)

1.聚合 (OR): 用 OR (|) 操作,把行、列、宫里用过的数字聚合,得到一个‘黑名单’。

2.取反 (NOT): 黑名单翻转为白名单,原来的黑名单变成了 0,而空闲的位置变成了 1。

但这里有个问题,计算机的整数是 32 位的,取反后高位全是 1(垃圾数据)。

3.过滤 (AND): 使用 511 (9个1) 筛除高位垃圾,锁定有效候选,只保留我们关心的 1-9 位。

4.以上只进行了3次计算即完成了一个格子的填充

以id=1为例,行、列、宫已有数字掩码聚合如下

以取第1行第2列、第4列空格为例

已有数字掩码分别为 (115|505|507) 和 (115|370|371),这两个空格可填数字计算如下

-- 遍历提取 (Iteration)-- 【核心特性】全量解析,结果完整-- 【适用场景】调试展示、回溯法分支生成 (需要所有可能性)WITH test_calc AS (    SELECT (511 & ~ (115|505|507)) as cand_m    union all    SELECT (511 & ~ (115|370|371)) as cand_m)SELECT    cand_m,    cand_m::bit(9) cand_m_bit,    (        SELECT string_agg(num::text, ',')        FROM generate_series(19) num        WHERE (cand_m & (1 << (num - 1))) > 0 -- 挨个检查1-9是否在掩码里    ) as candidates_list,    bit_count(cand_m::bit(9)) bit_count   --掩码为1的数量FROM test_calc;

即快速求解出两个格子可填数字分别为3 和 3、4、8

注意:第一组仅有一个值,这是大部分简单题普遍情况,对于这种情况可以简化如下,只取首个值快速计算,避免消耗过多计算资源进行循环碰撞

-- 单值提取 (Bit Hack),适用于只有唯一值时快速提取-- 【核心特性】极速计算,无循环-- 【适用场景】贪心阶段 (WHERE bit_count=1),确保只有唯一解时使用WITH test_calc AS (    SELECT (511 & ~ (115|505|507)) as cand_m    union all    SELECT (511 & ~ (115|370|371)) as cand_m)select    a.cand_m,                          --十进制表达    a.cand_m::bit(9)  as cand_m_bit,   --二进制表达    -- 【关键逻辑】利用 x & -x 提取最低位的 1 (Lowbit)    -- 如果有多个候选数,这里会丢失高位数据,只返回最小的那个数字,需要限制仅存在唯一候选情况下使用,即掩码为1的数量=1    (bit_count(((a.cand_m & -a.cand_m) - 1)::bit(32)) + 1)::smallint candidates_list,  --可选数字    bit_count(cand_m::bit(9)) bit_countfrom test_calc a;
适用范围:仅存在唯一候选情况下使用,即掩码为1的数量=1
where bit_count(cand_m::bit(9))=1

完整流程构建

待填格子位置索引

    ---待填格子位置索引:筛选出所有值为 0 的格子索引,打包为一个数组empty_calc AS (    SELECT id, array_agg(i::smallint ORDER BY i) as emp    FROM cells WHERE val = 0 GROUP BY id),

WHEREval= 0:

含义:这是过滤器。在数独逻辑中,0 代表空位(即原题中的 ? 或 .)。

作用:只关心那些“需要填”的格子,忽略那些题目自带的已知数字(1-9)。

i::smallint:

含义:i 是格子在 81 个字符长字符串中的绝对位置(1-81)。

作用:强制转换为 smallint(2字节整数)。内存优化的一部分,比默认的 int(4字节)省一半内存。

ORDER BY i:

含义:在打包数组时,按照位置先后排序。

作用:保证任务列表的顺序是确定性的(从左上角到右下角)。这对于后续递归逻辑的稳定性非常重要。

array_agg**(...) as emp**:

含义:聚合函数。将多行数据“捏”成一行里的一个数组。

结果:emp (Empty Cells) 字段。

递归前数据准备

-- 4. 组装初始状态--递归前数据准备prep AS (    SELECT        s.id, s.board,  --[零件1] 原始棋盘        -- [零件2] 约束掩码 (27个整数)        -- 这里包含了 9行+9列+9宫 的初始状态        COALESCE(m.ms, '{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}'::smallint[]) as ms,        -- [零件3] 待办空位数组 (递归的任务列表)        COALESCE(e.emp, '{}'::smallint[]) as emp    FROM src s     -- 将三个独立的数据流合并为一行    LEFT JOIN masks_calc m ON s.id = m.id    LEFT JOIN empty_calc e ON s.id = e.id),

prep CTE 数据准备:

1.Board:当前的棋盘。

2.Masks:长度为27的位掩码数组,因为它一次性存储了 9****行+ 9****列+ 9****宫 的所有位掩码。

3.Emp:待填格子位置索引。

4.COALESCE 和 LEFT JOIN。为了代码的健壮性——即使输入的数独已经是满的(没有空位,empty_calc 为 NULL),代码也不会报错,而是生成一个空任务列表,直接流转到结束状态

第一阶段简单题快速求解

-- 5. 第一阶段:贪心极速流 (确定性求解)solve_easy(id, board, ms, emp) AS (    SELECT id, board, ms, emp FROM prep    UNION ALL    SELECT        s.id,        -- 1. 更新棋盘:把原来的 0 替换成新的数字        s.board[:cell.p-1|| c.val::smallint || s.board[cell.p+1:],        -- 2. 更新掩码:把新数字加入到对应的行、列、宫的黑名单里        s.ms[:cell.r] || (s.ms[cell.r+1| c.bit_m)::smallint || s.ms[cell.r+2:9+cell.c] || (s.ms[10+cell.c] | c.bit_m)::smallint || s.ms[11+cell.c:18+cell.bx] || (s.ms[19+cell.bx] | c.bit_m)::smallint || s.ms[19+cell.bx+1:27],        ---- 3.移除已处理空格:从空位列表里移除当前位置        array_remove(s.emp, cell.p)    FROM solve_easy s    INNER JOIN LATERAL (        SELECT p, (p-1)/9 as r, (p-1)%9 as c, (p-1)/27*3+(p-1)%9/3 as bx, cand_m        FROM unnest(s.emp) p   -- 展开所有空位(emp)        CROSS JOIN LATERAL (   -- 计算候选掩码:全集(511) 剔除(AND NOT) 行列宫已有的数字            SELECT 511 & ~(s.ms[(p-1)/9+1]::int | s.ms[(p-1)%9+10]::int | s.ms[(p-1)/27*3+(p-1)%9/3+19]::intas cand_m        ) t        WHERE bit_count(cand_m::bit(9)) = 1     -- 【关键!】只要那些只有 1 个可能性的        LIMIT 1                                 -- 每次只抓一个,保持稳健    ) cell ON true    CROSS JOIN LATERAL (        -- 把二进制掩码转回 1-9 的十进制整数        SELECT (bit_count(((cell.cand_m & -cell.cand_m) - 1)::bit(32)) + 1)::smallint as val,               (cell.cand_m & -cell.cand_m)::int as bit_m    ) c),

A.扫描与计算(The Scanner)

核心代码:511 & ~(Row | Col | Box)

•利用位运算瞬间计算补集。这相当于问数据库:在这个位置,除了行、列、宫里已有的数字,还剩下什么能填?

B.贪心判定(The Filter)

代码:WHERE bit_count(...) = 1

•只有当某个格子在逻辑上只能填入一个数字时才行动。这保证了这一阶段的所有操作都是100% 正确的,不需要回溯。

C.状态更新(The Update)

代码:s.ms[...] || ... (复杂的数组拼接)

•使用PostgreSQL 的数组切片操作,在填入数字时同时更新了行、列、宫的位掩码。这确保了下一次递归时,约束条件是最新的。

逻辑分流

-- 6. 逻辑分流finished_easy AS (    -- [快速通道] 只要任务清单空了,直接结算,释放内存    SELECT id, board FROM solve_easy WHERE cardinality(emp) = 0),stuck_hard_input AS (    -- [优胜劣汰] 筛选出卡住的难题    SELECT DISTINCT ON (id) id, board, ms, emp    FROM solve_easy    WHERE id NOT IN (SELECT id FROM finished_easy)    -- [关键策略] 如果有多个中间状态,取剩余空位最少的那一个继续算    ORDER BY id, cardinality(emp) ASC),

A.内存保护(Memory Safety)

•面对 1 万道题,如果让已完成的题目继续参与后续的递归连接,会造成巨大的内存浪费。通过 finished_easy 立刻卸载已完成的数据,相当于给系统做了‘内存减负’,防止大数据量下的 磁盘溢出

B.优胜劣汰(Best-First Selection)

•在第一阶段,可能会产生同一题目的不同中间状态。利用 ORDER BY cardinality ASC,强行只保留完成度最高的那一个状态进入下一轮。这确保了后续的回溯搜索是从最佳起点开始的。

• PostgreSQL 特有的 DISTINCT ON 语法(比排序后limit 1高)

第二阶段-剩余难题处理--回溯补刀 (MRV 策略)

-- 7. 第二阶段:回溯补刀 (MRV 策略)solve_hard(id, board, ms, emp) AS (    SELECT id, board, ms, emp FROM stuck_hard_input  -- 接力棒:处理剩余的难题    UNION ALL    SELECT        s.id,        s.board[:cell.p-1|| v.val::smallint || s.board[cell.p+1:],        s.ms[:cell.r] || (s.ms[cell.r+1| v.bit_m)::smallint || s.ms[cell.r+2:9+cell.c] || (s.ms[10+cell.c] | v.bit_m)::smallint || s.ms[11+cell.c:18+cell.bx] || (s.ms[19+cell.bx] | v.bit_m)::smallint || s.ms[19+cell.bx+1:27],        array_remove(s.emp, cell.p)    FROM solve_hard s    JOIN LATERAL (        SELECT p, (p-1)/9 as r, (p-1)%9 as c, (p-1)/27*3+(p-1)%9/3 as bx, cand_m        FROM unnest(s.emp) p        CROSS JOIN LATERAL (            SELECT 511 & ~(s.ms[(p-1)/9+1]::int | s.ms[(p-1)%9+10]::int | s.ms[(p-1)/27*3+(p-1)%9/3+19]::intas cand_m        ) t        -- 【关键差异】不再寻找唯一解,而是寻找"可能性最少"的格子        ORDER BY bit_count(cand_m::bit(9)) ASC        LIMIT 1    ) cell ON true    JOIN LATERAL (        -- 【关键差异】展开所有可能的候选数        SELECT d+1 as val, 1<<as bit_m        FROM generate_series(0,8) d WHERE (cell.cand_m & (1<<d)) <> 0    ) v ON true)

最终合并输出

-- 8. 最终合并输出SELECT    f.id,    s.puzzle,   -- [延迟物化] 此时才去读取原始题面字符串,而非在复杂递归中带着消耗资源    -- f.board,  --结果数组,方便验证数据,最终输出时注释掉    -- 格式化输出: 数组转字符串,每9位换行    trim(both E'\n' FROM regexp_replace(array_to_string(f.board, ''), '(.{9})''\1' || E'\n''g')) as resultFROM (    SELECT id, board FROM finished_easy    UNION ALL    -- [去重] 再次确保每题只留一个解    SELECT DISTINCT ON (id) id, board FROM solve_hard WHERE cardinality(emp) = 0 ORDER BY id) fJOIN src s ON f.id = s.id;

A.延迟物化(Late Materialization)

在之前所有的递归计算中,没有携带 puzzle 这个原始字符串。因为字符串在内存中很占空间,且拷贝成本高。 只传递了 ID 和轻量级的 smallint 数组。直到最后一步,才通过 JOIN 把它拿回来。 这种延迟物化策略,可以节省一些内存提升性能。

B.结果整形(Result Formatting)

•利用了 PostgreSQL 强大的正则替换功能。 (.{9}) 匹配任意 9 个字符,\1\n 在其后插入换行符。这避免了写复杂的循环或应用层代码,直接在数据库层完成了数据的渲染


参赛完整SQL:
--用一条 SQL 解数独问题--数据库:PostgreSQL--提交人:周仟荣1WITH RECURSIVE-- 1. 数据源 & 强壮解析 (Robust Parsing)src AS (    SELECT        id,        puzzle,        -- 1. regexp_replace: 剔除所有非数字、非点、非问号的字符 (包括空格、换行、制表符等)        -- 2. translate: 再将 '.' 和 '?' 统一转为 '0'        -- 3. 结果: 得到纯净的 81 位数字字符串        string_to_array(            translate(                regexp_replace(puzzle, '[^0-9.?]''''g'),                '.?''00'            ),            NULL        )::smallint[] AS board    FROM sudoku9_9 -- 题面),-- 2. 拆解单元格坐标cells AS (    SELECT        id, val, i,   --id,原值,81位字符串序号        (i-1)/9 as r,   --行        (i-1)%9 as c,   --列        ((i-1)/27)*3 + ((i-1)%9)/3 as bx  --宫    FROM src, unnest(board) WITH ORDINALITY as t(val, i)   --数组展开为行),-- 3. 批量初始化掩码 (Filter 聚合)masks_calc AS (----使用“位掩码”技术。通过位运算(Bitwise OR)将每一行、列、宫中已有的数字记录在一个二进制数中    SELECT id, array_agg(COALESCE(m, 0)::smallint ORDER BY idx) as ms    FROM (        SELECT id, r+1 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, r        UNION ALL        SELECT id, c+10 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, c        UNION ALL        SELECT id, bx+19 as idx, bit_or(1 << (val-1)) FILTER (WHERE val>0as m FROM cells GROUP BY id, bx    ) t    GROUP BY id),    ---待填格子位置索引:筛选出所有值为 0 的格子索引,打包为一个数组empty_calc AS (    SELECT id, array_agg(i::smallint ORDER BY i) as emp    FROM cells WHERE val = 0 GROUP BY id),-- 4. 组装初始状态--递归前数据准备prep AS (    SELECT        s.id, s.board,  --[零件1] 原始棋盘        -- [零件2] 约束掩码 (27个整数)        -- 这里包含了 9行+9列+9宫 的初始状态        COALESCE(m.ms, '{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}'::smallint[]) as ms,        -- [零件3] 待办空位数组 (递归的任务列表)        COALESCE(e.emp, '{}'::smallint[]) as emp    FROM src s     -- 将三个独立的数据流合并为一行    LEFT JOIN masks_calc m ON s.id = m.id    LEFT JOIN empty_calc e ON s.id = e.id),-- 5. 第一阶段:贪心极速流 (确定性求解)solve_easy(id, board, ms, emp) AS (    SELECT id, board, ms, emp FROM prep    UNION ALL    SELECT        s.id,        -- 1. 更新棋盘:把原来的 0 替换成新的数字        s.board[:cell.p-1|| c.val::smallint || s.board[cell.p+1:],        -- 2. 更新掩码:把新数字加入到对应的行、列、宫的黑名单里        s.ms[:cell.r] || (s.ms[cell.r+1| c.bit_m)::smallint || s.ms[cell.r+2:9+cell.c] || (s.ms[10+cell.c] | c.bit_m)::smallint || s.ms[11+cell.c:18+cell.bx] || (s.ms[19+cell.bx] | c.bit_m)::smallint || s.ms[19+cell.bx+1:27],        ---- 3.移除已处理空格:从空位列表里移除当前位置        array_remove(s.emp, cell.p)    FROM solve_easy s    INNER JOIN LATERAL (        SELECT p, (p-1)/9 as r, (p-1)%9 as c, (p-1)/27*3+(p-1)%9/3 as bx, cand_m        FROM unnest(s.emp) p   -- 展开所有空位(emp)        CROSS JOIN LATERAL (   -- 计算候选掩码:全集(511) 剔除(AND NOT) 行列宫已有的数字            SELECT 511 & ~(s.ms[(p-1)/9+1]::int | s.ms[(p-1)%9+10]::int | s.ms[(p-1)/27*3+(p-1)%9/3+19]::intas cand_m        ) t        WHERE bit_count(cand_m::bit(9)) = 1     -- 【关键!】只要那些只有 1 个可能性的        LIMIT 1                                 -- 每次只抓一个,保持稳健    ) cell ON true    CROSS JOIN LATERAL (        -- 把二进制掩码转回 1-9 的十进制整数        SELECT (bit_count(((cell.cand_m & -cell.cand_m) - 1)::bit(32)) + 1)::smallint as val,               (cell.cand_m & -cell.cand_m)::int as bit_m    ) c),-- 6. 逻辑分流finished_easy AS (    -- [快速通道] 只要任务清单空了,直接结算,释放内存    SELECT id, board FROM solve_easy WHERE cardinality(emp) = 0),stuck_hard_input AS (    -- [优胜劣汰] 筛选出卡住的难题    SELECT DISTINCT ON (id) id, board, ms, emp    FROM solve_easy    WHERE id NOT IN (SELECT id FROM finished_easy)    -- [关键策略] 如果有多个中间状态,取剩余空位最少的那一个继续算    ORDER BY id, cardinality(emp) ASC),-- 7. 第二阶段:回溯补刀 (MRV 策略)solve_hard(id, board, ms, emp) AS (    SELECT id, board, ms, emp FROM stuck_hard_input  -- 接力棒:处理剩余的难题    UNION ALL    SELECT        s.id,        s.board[:cell.p-1|| v.val::smallint || s.board[cell.p+1:],        s.ms[:cell.r] || (s.ms[cell.r+1| v.bit_m)::smallint || s.ms[cell.r+2:9+cell.c] || (s.ms[10+cell.c] | v.bit_m)::smallint || s.ms[11+cell.c:18+cell.bx] || (s.ms[19+cell.bx] | v.bit_m)::smallint || s.ms[19+cell.bx+1:27],        array_remove(s.emp, cell.p)    FROM solve_hard s    JOIN LATERAL (        SELECT p, (p-1)/9 as r, (p-1)%9 as c, (p-1)/27*3+(p-1)%9/3 as bx, cand_m        FROM unnest(s.emp) p        CROSS JOIN LATERAL (            SELECT 511 & ~(s.ms[(p-1)/9+1]::int | s.ms[(p-1)%9+10]::int | s.ms[(p-1)/27*3+(p-1)%9/3+19]::intas cand_m        ) t        -- 【关键差异】不再寻找唯一解,而是寻找"可能性最少"的格子        ORDER BY bit_count(cand_m::bit(9)) ASC        LIMIT 1    ) cell ON true    JOIN LATERAL (        -- 【关键差异】展开所有可能的候选数        SELECT d+1 as val, 1<<as bit_m        FROM generate_series(0,8) d WHERE (cell.cand_m & (1<<d)) <> 0    ) v ON true)-- 8. 最终合并输出SELECT    f.id,    s.puzzle,   -- [延迟物化] 此时才去读取原始题面字符串,而非在复杂递归中带着消耗资源    -- f.board,  --结果数组,方便验证数据,最终输出时注释掉    -- 格式化输出: 数组转字符串,每9位换行    trim(both E'\n' FROM regexp_replace(array_to_string(f.board, ''), '(.{9})''\1' || E'\n''g')) as resultFROM (    SELECT id, board FROM finished_easy    UNION ALL    -- [去重] 再次确保每题只留一个解    SELECT DISTINCT ON (id) id, board FROM solve_hard WHERE cardinality(emp) = 0 ORDER BY id) fJOIN src s ON f.id = s.id;
《数据库编程大赛》
下一次再聚!

感谢大家对本次《数据库编程大赛》的关注和支持,欢迎加入技术交流群,更多精彩活动不断,欢迎各路数据库爱好者来挑战!

最新文章

随机文章

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-02-08 13:41:40 HTTP/2.0 GET : https://f.mffb.com.cn/a/466801.html
  2. 运行时间 : 0.089514s [ 吞吐率:11.17req/s ] 内存消耗:4,786.84kb 文件加载:140
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=166f1a2a90dcea988e0011ef7b4c845c
  1. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/composer/autoload_static.php ( 4.90 KB )
  7. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  10. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  11. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  12. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  13. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  14. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  15. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  16. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  17. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  18. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  19. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  21. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  22. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/provider.php ( 0.19 KB )
  23. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  24. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  25. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  26. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/common.php ( 0.03 KB )
  27. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  28. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  29. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/app.php ( 0.95 KB )
  30. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cache.php ( 0.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/console.php ( 0.23 KB )
  32. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/cookie.php ( 0.56 KB )
  33. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/database.php ( 2.48 KB )
  34. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  35. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/filesystem.php ( 0.61 KB )
  36. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/lang.php ( 0.91 KB )
  37. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/log.php ( 1.35 KB )
  38. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/middleware.php ( 0.19 KB )
  39. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/route.php ( 1.89 KB )
  40. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/session.php ( 0.57 KB )
  41. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/trace.php ( 0.34 KB )
  42. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/config/view.php ( 0.82 KB )
  43. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/event.php ( 0.25 KB )
  44. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  45. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/service.php ( 0.13 KB )
  46. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/AppService.php ( 0.26 KB )
  47. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  48. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  49. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  50. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  51. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  52. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/services.php ( 0.14 KB )
  53. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  54. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  55. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  56. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  57. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  58. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  59. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  60. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  61. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  62. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  63. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  64. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  65. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  66. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  67. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  68. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  69. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  70. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  71. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  72. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  73. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  74. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  75. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  76. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  77. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  78. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  79. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  80. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  81. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  82. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  83. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/Request.php ( 0.09 KB )
  84. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  85. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/middleware.php ( 0.25 KB )
  86. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  87. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  88. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  89. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  90. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  91. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  92. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  93. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  94. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  95. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  96. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  97. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  98. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  99. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/route/app.php ( 1.72 KB )
  100. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  101. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  102. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  103. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/controller/Index.php ( 4.81 KB )
  104. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/app/BaseController.php ( 2.05 KB )
  105. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  106. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  108. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  109. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  110. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  111. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  112. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  113. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  114. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  115. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  116. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  117. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  118. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  119. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  120. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  121. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  122. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  123. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  124. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  125. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  126. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  127. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  128. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  129. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  130. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  131. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  132. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  133. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  134. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  135. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  136. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  137. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  138. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  139. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/runtime/temp/067d451b9a0c665040f3f1bdd3293d68.php ( 11.98 KB )
  140. /yingpanguazai/ssd/ssd1/www/f.mffb.com.cn/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.000599s ] mysql:host=127.0.0.1;port=3306;dbname=f_mffb;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.000715s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.000312s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.000283s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.000485s ]
  6. SELECT * FROM `set` [ RunTime:0.000191s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.000561s ]
  8. SELECT * FROM `article` WHERE `id` = 466801 LIMIT 1 [ RunTime:0.000584s ]
  9. UPDATE `article` SET `lasttime` = 1770529300 WHERE `id` = 466801 [ RunTime:0.000686s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 65 LIMIT 1 [ RunTime:0.000212s ]
  11. SELECT * FROM `article` WHERE `id` < 466801 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.000467s ]
  12. SELECT * FROM `article` WHERE `id` > 466801 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.002085s ]
  13. SELECT * FROM `article` WHERE `id` < 466801 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.011260s ]
  14. SELECT * FROM `article` WHERE `id` < 466801 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.000992s ]
  15. SELECT * FROM `article` WHERE `id` < 466801 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.000919s ]
0.091231s