利用多种方法实现SQL行列转换
一、 背景SQL用于统计数据分析过程中行列转换是一项常见的操作。按转化方向划分行列转换可分为行转列、列转行按转化内容划分可分为行列转字符串、字符串转行列等。受SQL语句语法限制传统的数据库数据类型在处理行列转换上不很方便要么语句冗长要么要借助存储过程来实现有的数据库管理系统则用特定的函数来实现。并与传统的方法比较。为了解决这一问题下面利用一些数据库管理系统引入的数组数据类型来比较方便高效地完成部分转换工作。二、 数据准备我们使用一张学生表T作为我们的基础表。用它来演示各种类型的行列转换操作。假定表中主键是学号学期科目。数据库管理系统采用duckdb它的语法与PostgreSQL兼容 。多种国产数据库产品也与之兼容如金仓数据库。表0.成绩登记表┌───────┬───────┬───────┬───────┐ │ a │ b │ c │ d │ │ 学号 │ 学期 │ 科目 │ 分数 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴───────┘简单起见用a,b,c,d分别表示学号、学期、科目、分数建表语句如下create table t(a smallint,b smallint,c smallint,d smallint, primary key(a,b,c));插入模拟数据语句a,b,c中的每个都取1、2两个值insert into t with a(n) as(select 1 union select 2)select a.n,b.n,c.n,a.nb.nc.n from a,a b,a c;为了表示某些数据缺失情况将表格中特定的行删除。语句如下delete from t where (a,b,c)in((2,2,1));三、 行转列就是把多个行某一列的值用多个列来展示。假定我们有3种表需要显示。表1.按学号和学期显示不同科目的分数学号 学期 科目1分数 科目2分数表2.按学号和科目显示不同学期的分数学号 科目 学期1分数 学期2分数表3.按学号显示不同科目和学期的分数学号 科目1学期1分数 科目1学期2分数 科目2学期1分数 科目2学期2分数一 使用case when行转列表1的查询语句select a,b,max(case when c1 then d end)c1, max(case when c2 then d end)c2 from t group by a,b; ┌───────┬───────┬───────┬───────┐ │ a │ b │ c1 │ c2 │ │ 学号 │ 学期 │ 科目1 │ 科目2 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 3 │ 4 │ │ 1 │ 2 │ 4 │ 5 │ │ 2 │ 1 │ 4 │ 5 │ │ 2 │ 2 │ NULL │ 6 │ └───────┴───────┴───────┴───────┘上述语句的含义是将每种a,b组合中符合条件c1和c2的d值分别用max求出每列都需要一个case when语句如果显示某个列的条件包含多个列则多个列的条件都需要在when中写出。表2的查询语句select a,c,max(case when b1 then d end)b1, max(case when b2 then d end)b2 from t group by a,c; ┌───────┬───────┬───────┬───────┐ │ a │ c │ b1 │ b2 │ │ 学号 │ 科目 │ 学期1 │ 学期2 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 3 │ 4 │ │ 1 │ 2 │ 4 │ 5 │ │ 2 │ 1 │ 4 │ NULL │ │ 2 │ 2 │ 5 │ 6 │ └───────┴───────┴───────┴───────┘表3的查询语句select a,max(case when b1 and c1 then d end)b1c1, max(case when b1 and c2 then d end)b1c2, max(case when b2 and c1 then d end)b2c1, max(case when b2 and c2 then d end)b2c2 from t group by a; ┌───────┬───────┬───────┬───────┬───────┐ │ a │ b1c1 │ b1c2 │ b2c1 │ b2c2 │ │ 学号 │ int16 │ int16 │ int16 │ int16 │ ├───────┼───────┼───────┼───────┼───────┤ │ 1 │ 3 │ 4 │ 4 │ 5 │ │ 2 │ 4 │ 5 │ NULL │ 6 │ └───────┴───────┴───────┴───────┴───────┘二 PostgreSQL使用crosstab行转列表1的查询语句select a/10 a,a%10 b,c1,c2 from crosstab(select a*10b,c,d from t order by a,b,c,$$VALUES(1),(2)$$) as d(a int ,c1 int,c2 int);其中crosstab函数是一个扩展函数需要用命令create extension tablefunc;启用它包含2个参数参数1是一个查询必须是3列分别是行分组列、列分组列、取值列。参数2是一个查询或值的列表表示列分组列的取值和次序。这里的$$VALUES(1),(2)$$可以等价替换成select distinct c from t order by c。as子句表示将crosstab的返回结果设置一个表别名列别名和类型列表最前面的select 子句的列名均引用自此表别名。由于crosstab只支持一列作为行分组列所以此处使用了一个合并后拆分的手段如果取值不是简单的1位整数则需要改为其他写法。表2的查询语句select a/10 a,a%10 c,b1,b2 from crosstab(select a*10c,b,d from t order by a,c,b,$$VALUES(1),(2)$$) as d(a int ,b1 int,b2 int);表3的查询语句select a,b1c1,b1c2,b2c1,b2c2 from crosstab(select a,b*10c,d from t order by a,c,b,$$VALUES(11),(12),(21),(22)$$) as d(a int , b1c1 int,b1c2 int,b2c1 int,b2c2 int);三 使用数组函数array_agg行转列表1的查询语句with a(n) as(select 1 union select 2),t1 as(select a.n a,b.n b,c.n c from a,a b,a c) select a,b,array_agg(coalesce(d,0) order by c)d from t1 left join t using(a,b,c) group by a,b order by 1, 2; ┌───────┬───────┬─────────┐ │ a │ b │ d │ │ int32 │ int32 │ int16[] │ ├───────┼───────┼─────────┤ │ 1 │ 1 │ [3, 4] │ │ 1 │ 2 │ [4, 5] │ │ 2 │ 1 │ [4, 5] │ │ 2 │ 2 │ [0, 6] │ └───────┴───────┴─────────┘这个语句的with部分的t1表示a,b,c三列的全组合也就是笛卡尔积。coalesce函数表示在d的值为NULL时将其替换成0若无需替换则可省略coalesce函数输出变为┌───────┬───────┬───────────┐ │ a │ b │ d │ │ int32 │ int32 │ int16[] │ ├───────┼───────┼───────────┤ │ 1 │ 1 │ [3, 4] │ │ 1 │ 2 │ [4, 5] │ │ 2 │ 1 │ [4, 5] │ │ 2 │ 2 │ [NULL, 6] │ └───────┴───────┴───────────┘left join表示将上述t1与基础表左连接之所以这样做是为了当某个学生缺少某学期某科目成绩时能够显示0或NULL而不至于错位。如果不存在这种情况每个学生都有全部的成绩简单地select a,b,array_agg(d order by c)d from t group by a,b order by 1, 2即可。表示行方向按a,b分组列方向按c顺序列举。如果要得表2的结果with a(n) as(select 1 union select 2),t1 as(select a.n a,b.n b,c.n c from a,a b,a c) select a,c,array_agg(d order by a,c)d from t1 left join t using(a,b,c)group by a,c order by 1,2; ┌───────┬───────┬───────────┐ │ a │ c │ d │ │ int32 │ int32 │ int16[] │ ├───────┼───────┼───────────┤ │ 1 │ 1 │ [3, 4] │ │ 1 │ 2 │ [4, 5] │ │ 2 │ 1 │ [4, NULL] │ │ 2 │ 2 │ [5, 6] │ └───────┴───────┴───────────┘若学生都有全部的成绩只需要简单地改变分组和排序列select a,c,array_agg(d order by b)d from t group by a,c order by 1, 2即可。如果要得表3的结果with a(n) as(select 1 union select 2),t1 as(select a.n a,b.n b,c.n c from a,a b,a c) select a,array_agg(d order by b,c)d from t1 left join t using(a,b,c)group by a order by 1; ┌───────┬─────────────────┐ │ a │ d │ │ int32 │ int16[] │ ├───────┼─────────────────┤ │ 1 │ [3, 4, 4, 5] │ │ 2 │ [4, 5, NULL, 6] │ └───────┴─────────────────┘若学生都有全部的成绩只需要将b从分组列改为排序列select a,array_agg(d order by b,c)d from t group by a order by 1即可。要将数组数据类型中的元素取出采用数组[序号]的语法序号从1开始编号。比如要把上述表3的数组类型结果转化为多列结果这样编写with a as(select a,array_agg(d order by b,c)d from t group by a)select a,d[1]b1c1,d[2]b1c2,d[3]b2c1,d[4]b2c2 from a; ┌───────┬───────┬───────┬───────┬───────┐ │ a │ b1c1 │ b1c2 │ b2c1 │ b2c2 │ │ int16 │ int16 │ int16 │ int16 │ int16 │ ├───────┼───────┼───────┼───────┼───────┤ │ 1 │ 3 │ 4 │ 4 │ 5 │ │ 2 │ 4 │ 5 │ 6 │ NULL │ └───────┴───────┴───────┴───────┴───────┘因为未与全组合的表关联上述结果的NULL就发生了错位。 错把a2b2c2的结果填在了a2b2c1的位置。四 DuckDB使用pivot行转列duckdb行列转换有更简洁的pivot和unpivot语法如下所示D pivot t on c using sum(d); ┌───────┬───────┬────────┬────────┐ │ a │ b │ 1 │ 2 │ │ int16 │ int16 │ int128 │ int128 │ ├───────┼───────┼────────┼────────┤ │ 1 │ 1 │ 3 │ 4 │ │ 1 │ 2 │ 4 │ 5 │ │ 2 │ 1 │ 4 │ 5 │ │ 2 │ 2 │ NULL │ 6 │ └───────┴───────┴────────┴────────┘ D pivot t on b using sum(d); ┌───────┬───────┬────────┬────────┐ │ a │ c │ 1 │ 2 │ │ int16 │ int16 │ int128 │ int128 │ ├───────┼───────┼────────┼────────┤ │ 1 │ 1 │ 3 │ 4 │ │ 1 │ 2 │ 4 │ 5 │ │ 2 │ 1 │ 4 │ NULL │ │ 2 │ 2 │ 5 │ 6 │ └───────┴───────┴────────┴────────┘ D pivot t on b,c using sum(d); ┌───────┬────────┬────────┬────────┬────────┐ │ a │ 1_1 │ 1_2 │ 2_1 │ 2_2 │ │ int16 │ int128 │ int128 │ int128 │ int128 │ ├───────┼────────┼────────┼────────┼────────┤ │ 1 │ 3 │ 4 │ 4 │ 5 │ │ 2 │ 4 │ 5 │ NULL │ 6 │ └───────┴────────┴────────┴────────┴────────┘详细用法参见文档四、 列转行列转行是行转列的逆操作就是把多个列的值用多行一列来展示对我们的例子从表1、2、3得到表0的结果都属于列转行。为减少篇幅仅用较复杂的多列表3来得到表1举例其他可以仿照表3的处理来完成。首先将表3查询结果用create table as保存为数据库表T3。create table t3 as select a,max(case when b1 and c1 then d end)b1c1, max(case when b1 and c2 then d end)b1c2, max(case when b2 and c1 then d end)b2c1, max(case when b2 and c2 then d end)b2c2 from t group by a;最容易想到的方法是将不同列的查询结果逐个取出再用union all合并但此法有多少列就需要读多少次原表因此对大表而言不可行。一 使用case when列转行使用case when列转行的原理是通过与一个行数与需转换列数相同每行都有一个行号的中间表做笛卡尔积将每个列映射到某个行号再将行号与原始表关联将对应的分组列输出with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c) ┌───────┬───────┬───────┐ │ rn │ b │ c │ │ int64 │ int32 │ int32 │ ├───────┼───────┼───────┤ │ 1 │ 1 │ 1 │ │ 2 │ 1 │ 2 │ │ 3 │ 2 │ 1 │ │ 4 │ 2 │ 2 │ └───────┴───────┴───────┘ with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c) select t3.a,t1.b,t1.c,case rn when 1 then b1c1 when 2 then b1c2 when 3 then b2c1 when 4 then b2c2 end d from t1, t3; ┌───────┬───────┬───────┬───────┐ │ a │ b │ c │ d │ │ int16 │ int32 │ int32 │ int16 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 1 │ NULL │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴───────┘二 使用JOIN LATERAL列转行crosstab只能做行转列操作列转行可利用PostgreSQL的另一功能JOIN LATERAL完成它本质上与case when列转行的思路一致不过形式更为简明。SELECT t.a, b,c, d FROM t3 t CROSS JOIN LATERAL (VALUES(1,1, t.b1c1),(1,2, t.b1c2),(2,1,t.b2c1) ,(2,2,t.b2c2)) s(b,c, d); ┌───────┬───────┬───────┬───────┐ │ a │ b │ c │ d │ │ int16 │ int32 │ int32 │ int16 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 1 │ NULL │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴───────┘三 使用数组列转行对于常规数据类型的结果表列转行数组没有什么用。create table t3a as with a(n) as(select 1 union select 2),t1 as(select a.n a,b.n b,c.n c from a,a b,a c)select a,array_agg(d order by b,c)d from t1 left join t using(a,b,c)group by a order by 1; select * from t3a; ┌───────┬─────────────────┐ │ a │ d │ │ int32 │ int16[] │ ├───────┼─────────────────┤ │ 1 │ [3, 4, 4, 5] │ │ 2 │ [4, 5, NULL, 6] │ └───────┴─────────────────┘要将数组数据类型的数据列转行比如要将上述按a行转数组列的结果表t3a恢复为基础表可以将它与b,c两列的全组合连接并以b,c两列组合的序号为下标取出数组元素得到。此处关键是要按照同样的顺序去关联结果表和全组合表。with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c)select a,b,c,d[rn]d from t1,t3a; ┌───────┬───────┬───────┬───────┐ │ a │ b │ c │ d │ │ int32 │ int32 │ int32 │ int16 │ ├───────┼───────┼───────┼───────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 1 │ NULL │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴───────┘数组转行还可以使用unnest函数实现上述语句的等价写法如下with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c) select t3a.a,t1.b,t1.c,u.d from t3a,unnest(d) with ordinality as u(d,i),t1 where t1.rnu.i order by 1,2,3;这种写法稍微费解一点在from语句中unnest(d)引用的是t3a表的d列with ordinality表示拆分数组的同时产生序号拆出的元素存在表别名u的d列序号存在i列利用这个序号与t1表作关联。在这个场合不如用数组下标的方法简明。五、 行转字符串仍以表3为例如果要把分数列用一个字符串表示这通过专门函数string_agg实现用法与array_agg基本一致只是增加了一个分隔字符的参数select a,string_agg(d::varchar,, order by b,c)d from t group by a; ┌───────┬─────────┐ │ a │ d │ │ int16 │ varchar │ ├───────┼─────────┤ │ 1 │ 3,4,4,5 │ │ 2 │ 4,5,6 │ └───────┴─────────┘注意 string_agg函数忽略NULL, 如果要处理NULL需要像前面一样用全组合表左连接再用coalesce函数转换。with a(n) as(select 1 union select 2),t1 as(select a.n a,b.n b,c.n c from a,a b,a c) select a,string_agg(coalesce(d::varchar,NULL),, order by b,c)d from t1 left join t using (a,b,c) group by a order by 1; ┌───────┬────────────┐ │ a │ d │ │ int32 │ varchar │ ├───────┼────────────┤ │ 1 │ 3,4,4,5 │ │ 2 │ 4,5,NULL,6 │ └───────┴────────────┘六、 字符串转行split_part函数用于将指定分隔符的字符串的某个部分取出它的第一个参数是字符串第二个是分隔符第三个是序号用int类型。将上述string_agg转换的结果存为临时表ts转换为表0的操作如下with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c) select a,b,c,split_part(d,,,rn::int)d::int from t1 ,ts order by 1,2,3; ┌───────┬───────┬───────┬─────────┐ │ a │ b │ c │ d │ │ int32 │ int32 │ int32 │ varchar │ ├───────┼───────┼───────┼─────────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 1 │ NULL │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴─────────┘这个结果比原始表多了1行d为NULL的行可以用where d NULL’过滤掉。数据类型也不对可以过滤之后再转换为整数。regexp_split_to_table 和 regexp_split_to_array 都是字符串分割函数可通过指定的表达式进行分割。regexp_split_to_table 将分割出的数据转成行这个函数不能输出序号因此也难以与带序号的其它表关联。regexp_split_to_array 是将分隔的数据转成数组,它可以用下标方式取出所需的元素值。上述split_part查询的regexp_split_to_array等效语句如下with a(n) as(select 1 union select 2),t1 as(select row_number()over(order by b,c)rn,b.n b,c.n c from a b,a c),t2 as(select a,regexp_split_to_array(d,,)d from ts) select a,b,c,d[rn]d from t1 ,t2 order by 1,2,3; ┌───────┬───────┬───────┬─────────┐ │ a │ b │ c │ d │ │ int32 │ int32 │ int32 │ varchar │ ├───────┼───────┼───────┼─────────┤ │ 1 │ 1 │ 1 │ 3 │ │ 1 │ 1 │ 2 │ 4 │ │ 1 │ 2 │ 1 │ 4 │ │ 1 │ 2 │ 2 │ 5 │ │ 2 │ 1 │ 1 │ 4 │ │ 2 │ 1 │ 2 │ 5 │ │ 2 │ 2 │ 1 │ NULL │ │ 2 │ 2 │ 2 │ 6 │ └───────┴───────┴───────┴─────────┘string_to_array函数的功能与regexp_split_to_array相同。七、 结论case when通用性好适合于几乎所有关系型数据库。缺点是当输出列较多时写法过于冗长不易编写编写工作效率较低。数组函数array_agg和crosstab扩展函数相比具有如下优点可读性好不需要标出数据类型。可扩展性好可以推广到多个分组不需要特殊处理。可维护性好改变分组只需要改变分组列和排序列。通用性较好其他数据库管理系统如duckdb可兼容这种写法。使用数组的缺点是它不是标准数据类型有些数据库不支持。用下标访问数组元素时不同数据库管理系统的起始值可能不同如较早版本的duckdb的数组下标从0开始计数PostgreSQL从1开始计数需要注意。

相关新闻

【强烈推荐】大模型开发者必看:AI智能体90%是软件工程,10%是AI的真相

【强烈推荐】大模型开发者必看:AI智能体90%是软件工程,10%是AI的真相

过去两年,AI智能体(AI Agent)成为AI落地的热门方向。从 ChatGPT 的对话助手,到自动化办公、代码助手,再到多智能体协作平台,智能体被视为未来人机交互的核心形态。 然而在实际落地中,很多企业会…

2026/7/3 15:19:01 阅读更多 →
C++函数进阶:默认参数与函数重载,让你的代码更智能!

C++函数进阶:默认参数与函数重载,让你的代码更智能!

C函数进阶:默认参数与函数重载,让你的代码更智能! 大家好!今天我们来聊聊C中两个非常实用的特性:默认参数和函数重载。这两个特性能让我们的代码更灵活、更简洁,提高开发效率。 一、默认参数:让…

2026/7/3 0:50:59 阅读更多 →
毕业设计 深度学习异常流量检测系统(算法+论文)

毕业设计 深度学习异常流量检测系统(算法+论文)

文章目录 0 前言1 项目运行效果2 设计原理3 背景4 恶意软件加密流量介绍4.1 恶意软件分类4.2 恶意软件加密通信方式 5 加密HTTPS流量解析5.1 Https简介 6 流量解析6.1 流量解析日志生成6.2 流量解析日志中的数据关联6.3 流量解析的证书日志 7 机器学习特征分类7.1 构建4元组7.2…

2026/7/3 15:19:05 阅读更多 →

最新新闻

量子计算误差缓解:零噪声外推技术原理与实践

量子计算误差缓解:零噪声外推技术原理与实践

1. 量子计算中的噪声挑战与误差缓解技术概述在当前的NISQ(Noisy Intermediate-Scale Quantum)时代,量子处理器面临着严重的噪声干扰问题。以典型的超导量子比特为例,单比特门错误率约为10^-3量级,两比特门错误率可达10…

2026/7/4 13:13:15 阅读更多 →
GBFR-Logs终极指南:如何用数据提升你的《碧蓝幻想:Relink》战斗表现

GBFR-Logs终极指南:如何用数据提升你的《碧蓝幻想:Relink》战斗表现

GBFR-Logs终极指南:如何用数据提升你的《碧蓝幻想:Relink》战斗表现 【免费下载链接】gbfr-logs GBFR Logs lets you track damage statistics with a nice overlay DPS meter for Granblue Fantasy: Relink. 项目地址: https://gitcode.com/gh_mirror…

2026/7/4 13:11:15 阅读更多 →
AI辅助毕业论文写作:合规工具与实战技巧

AI辅助毕业论文写作:合规工具与实战技巧

1. 毕业论文AI辅助工具全景指南 作为一名经历过本科、硕士、博士论文洗礼的"老油条",我深知写论文的痛苦——从选题到查重,每个环节都能让人掉一把头发。如今AI工具井喷式发展,但市面上90%的推荐清单都存在两个致命问题&#xff1a…

2026/7/4 13:11:14 阅读更多 →
电商数据采集中的行为指纹混淆技术实战

电商数据采集中的行为指纹混淆技术实战

1. 项目背景与核心价值 去年在处理某电商平台数据采集项目时,我们团队遇到了一个棘手问题:无论怎么调整请求间隔、更换代理IP,目标站点的反爬系统总能在48小时内准确识别并封禁我们的爬虫。直到尝试了"行为指纹混淆"技术后&#xf…

2026/7/4 13:09:14 阅读更多 →
2022年6月AI工程化趋势:量化、提示词工业化与可观测服务

2022年6月AI工程化趋势:量化、提示词工业化与可观测服务

1. 这不是一份“新闻简报”,而是一份AI从业者六月实操现场的切片回放 2022年6月,AI圈没有爆炸性新模型发布,没有颠覆性论文刷屏,但整个行业的毛细血管正在发生肉眼可见的搏动。我那个月同时在三个项目里踩坑:一个用Sta…

2026/7/4 13:09:14 阅读更多 →
2025届毕业生实测:10大AI科研平台效率提升指南

2025届毕业生实测:10大AI科研平台效率提升指南

1. 项目背景与价值解析 作为2025届即将毕业的理工科学生,我深刻体会到优质科研资源对学术产出的决定性影响。在完成3篇SCI论文和2项专利的过程中,我系统测试了37个主流AI科研平台,最终筛选出10个真正能提升研究效率的实用工具。这份实测报告不…

2026/7/4 13:09:14 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻