MySQL:将单行结果放在单独的列中

如何解决MySQL:将单行结果放在单独的列中

我使用的是MySQL 5.7.31版,但在需要时仅安装了MySQL服务器8版

我有一个表,其中包含有关实体的一系列信息,例如:

+------+-----+  
| Name | Age |  
+------+-----+  
| Bob  |  22 |  
| Jack |  15 |  
| Jane |  25 |    
+------+-----+

在另一个表格中,我获得了有关哪些技能属于姓名和年龄的组合的信息,如下所示:

+-------------+------+-----+  
|    Skill    | Name | Age |  
+-------------+------+-----+  
| programming | Bob  |  22 |  
| programming | Jane |  25 |  
| marketing   | Jane |  25 |  
+-------------+------+-----+

这使我能够选择25岁的简的所有技能-返回2行。但是,我需要在如下所示的最终视图中将这些实体分别放入每个实体的列中,而我正在努力弄清楚如何做到这一点。当我在上面显示的表格中获得其他行时,该视图应继续工作

+------+-----+-------------+-----------+--------+  
| Name | Age |   skill1    |  skill2   | skill3 |  
+------+-----+-------------+-----------+--------+  
| Bob  |  22 | programming | Na        | Na     |  
| Jack |  15 | Na          | Na        | Na     |  
| Jane |  25 | programming | marketing | Na     |  
+------+-----+-------------+-----------+--------+

解决方法

您可以使用row_number()和条件聚合。假设这些表分别称为personsperson_skills

select p.name,p.age,max(case when ps.rn = 1 then ps.skill end) skill1,max(case when ps.rn = 2 then ps.skill end) skill2,max(case when ps.rn = 3 then ps.skill end) skill3
from persons p
left join (
    select ps.*,row_number() over(partition by name,age order by id) rn
    from person_skills ps
) ps on ps.name = p.name and ps.age = p.age
group by p.name,p.age

目前尚不清楚您希望将哪种技能分布到各个列上。假设您有一个名为id的排序列,可用于此目的。

,

如果要在MySQL 5.7的单独列中使用它们,则可能最简单的方法是关联子查询:

select p.*,(select ps.skill
        from person_skills ps
        where ps.name = p.name and ps.age = p.age
        order by ps.skill
        limit 1 offset 0
       ) as skill_1,(select ps.skill
        from person_skills ps
        where ps.name = p.name and ps.age = p.age
        order by ps.skill
        limit 1 offset 1
       ) as skill_2,(select ps.skill
        from person_skills ps
        where ps.name = p.name and ps.age = p.age
        order by ps.skill
        limit 1 offset 2
       ) as skill_3
from persons p;

这看起来很复杂,但是除了offset之外,这三个子查询都是相同的。

注意:如果没有可用的技能,它将返回NULL而不是'NA'。这是表示不可用值的典型方法。

如果您确实需要'NA',则可以使用COALESCE()

coalesce( (select ps.skill
           from person_skills ps
           where ps.name = p.name and ps.age = p.age
           order by ps.skill
           limit 1 offset 0
          ),'NA') as skill_1,

较早版本中的另一种替代方法是使用group_concat()进行黑客攻击:

select p.name,substring_index(group_concat(ps.skill order by ps.skill),',1) as skill_1,substring_index(substring_index(group_concat(ps.skill order by ps.skill),2),-1) as skill_2,3),-1) as skill_3
from persons p left join
     person_skills ps
     on ps.name = p.name and ps.age = p.age
group by p.name,p.age;

这会将所有技能聚合到一个字符串中,然后提取 nth 元素。

对于'NA',您将像上面一样使用COALESCE()

,

您可以使用GROUP_CONCAT聚合函数来获取逗号分隔的技能列表:

select
    Users.Name,Users.Age,GROUP_CONCAT(Skill) AS Skills
from Users
left join Skills on Skills.Name = Users.Name
group by Users.Name,Users.Age
;

这里是小提琴SQLize.online

结果

Name    Age    Skills
Bob     22     programming
Jack    15     NULL
Jane    25     programming,marketing

如果技能计数有限,可以使用下一个查询:

select
    Users.Name,GROUP_CONCAT(if(Skill='programming','programming',NULL)) AS Skill1,GROUP_CONCAT(if(Skill='marketing','marketing',NULL)) AS Skill2
from Users
left join Skills on Skills.Name = Users.Name
group by Users.Name,Users.Age
;

提琴here

,

好的,您在这里做的基本上是错误的,这不是您应该如何对待关系数据库的方法,这是一种边缘性的滥用。

关系数据库第101课,始终使用索引自动递增的主键。总是! (很抱歉,但要使用许多不了解此基础知识的人设计的系统,这会使性能变得疯狂)。

这是您的用户表的外观。

+----+------+-----+  
| id | Name | Age |  
+----+------+-----+  
|  1 | Bob  |  22 |  
|  2 | Jack |  15 |  
|  3 | Jane |  25 |    
+----+------+-----+

技能表

+----+--------------+
| id | skill        |
+----+--------------+
|  1 | programming  |
|  2 | Marketing    |
+----+--------------+

链接表

+----+---------+--------+
| id | skillId | userId |
+----+---------+--------+
|  1 |       1 |      3 |
|  2 |       2 |      3 |
|  3 |       1 |      1 |
+----+---------+--------+

现在对SQL本身来说,从您的示例中看来,您似乎总是希望将技能1和市场营销编程为技能2,在这种情况下(我们使用max和group by来使每个用户仅获得一行)。 / p>

SELECT 
    u.name Name,u.age Age,MAX(CASE WHEN s.id = 1 THEN s.skill ELSE NULL END) Skill1,-- Programmer 
    MAX(CASE WHEN s.id = 2 THEN s.skill ELSE NULL END) Skill2  -- Marketing
FROM 
    users u
LEFT JOIN 
    linktable l ON l.userId = u.id
LEFT JOIN 
    skills s ON s.id = l.skillsId
GROUP BY 
    u.name,u.age

显然,最好的办法是使用group_concat,就像其他人建议的那样,但是您必须在一栏中处理所有结果,但是可以处理不限数量的技能。

SELECT 
    u.name Name,GROUP_CONCAT(s.skill) Skills
FROM 
    users u
LEFT JOIN 
    linktable l ON l.userId = u.id
LEFT JOIN 
    skills s ON s.id = l.skillsId
GROUP BY 
    u.name,u.age
,

首先以一种可以使用确定条件的方式创建表结构...在数据透视选项

中进行更多搜索

这里是这种情况的一个例子

Create table Person (FName varchar(20),LName varchar(20),Age Int);

Insert into Person values 
('Jacke','W',29),('Prince','P',30),('Rush','B',29);


Create table Speciality (FName varchar(20),Skill varchar(20),Technology varchar(30));

Insert into Speciality values 
('Jacke','Skill1','Java'),('Jacke','Skill2','Unix'),'Skill3','PHP'),'.Net'),'Python'),'Notepad++'),'Office 365'),'.Net');

select P.FName,p.LName,p.Age,MAX(IF(Skill = 'Skill1',Technology,MAX(IF(Skill = 'Skill2',NULL)) AS Skill2,MAX(IF(Skill = 'Skill3',NULL)) AS Skill3
from Person P,Speciality S
where P.FName=S.Fname
group by P.FName,p.Age;

+--------+-------+------+------------+--------+-----------+
| FName  | LName | Age  | Skill1     | Skill2 | Skill3    |
+--------+-------+------+------------+--------+-----------+
| Jacke  | W     |   29 | Java       | Unix   | PHP       |
| Prince | P     |   30 | .Net       | Python | Notepad++ |
| Rush   | B     |   29 | Office 365 | .Net   | NULL      |
+--------+-------+------+------------+--------+-----------+

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)> insert overwrite table dwd_trade_cart_add_inc > select data.id, > data.user_id, > data.course_id, > date_format(
错误1 hive (edu)> insert into huanhuan values(1,'haoge'); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive> show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 <configuration> <property> <name>yarn.nodemanager.res