SQL四种方法实现行列转换超详细

本文详细介绍了如何使用SQL进行列转行和行转列的操作,包括使用JOIN、NATURAL JOIN、UNION ALL及IF函数的方法,并通过实际案例进行演示。通过这些技巧,你可以更灵活地处理数据库中的数据。
摘要由CSDN通过智能技术生成

前言

大家好,我是楚生辉,在未来的日子里我们一起来学习大数据SQL相关的技术,一起努力奋斗,遇见更好的自己!

本文详细的介绍了多个方法实现列转行,行转列,并提供了案例的材料,有需要的小伙伴可以自行获取与学习~

  • 数据准备
 CREATE TABLE `score` (
   `id` varchar(255),
   `subject` char(10),
   `score` int
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
 insert  into `score`(`id`,`subject`,`score`) values ('1','MATH',90),('1','ENGLISH',98),('1','CHINESE',85),('2','MATH',87),('2','ENGLISH',78),('2','CHINESE',89);

ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

1.使用join拼接

 SELECT id,score as 'MATH' FROM score WHERE subject = 'MATH';

我们把其他几门科目的成绩查出来后当做临时表再使用join不就解决了该问题吗?!而连接条件便是std。看到这,大家可以自己试一试。完整代码如下:

SELECT * FROM
	( SELECT id, score AS 'MATH' FROM score WHERE subject = 'MATH' ) AS t1
	JOIN ( SELECT id, score FROM score WHERE subject = 'ENGLISH' ) AS t2 ON t1.id = t2.id
	JOIN ( SELECT id, score FROM score WHERE subject = 'CHINESE' ) AS t3 ON t1.id = t3.id

ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述
然后我们只需要对上述的结果,挑选出我们想要的数据即可

SELECT t1.id, t1.MATH, t2.score AS 'ENGLISH',t3.score AS 'CHINESE' FROM
	( SELECT id, score AS 'MATH' FROM score WHERE subject = 'MATH' ) AS t1
	JOIN ( SELECT id, score FROM score WHERE subject = 'ENGLISH' ) AS t2 ON t1.id = t2.id
	JOIN ( SELECT id, score FROM score WHERE subject = 'CHINESE' ) AS t3 ON t1.id = t3.id

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

2.自然拼接

自动的寻找2表中的(所有)同名且属性相同的列作为连接条件。使用natural join子句来完成。
例如:A表中有列a,b,c,d B表中有a,b,x,z
自然连接会将A.a=B.a and A.b=B.b 作为连接条件
select * from A natural join B (natural 不可以省略)。他们所得的结果中,同名且属性相同的字段只显示一个。

对于自然连接而言,连接两个table之后,两个table共用的属性就会合并在一起。如果连个table没有共有的属性,则进行笛卡尔乘积,也就是进行两两相乘,如果table 1有3行,table 2有4行,自然连接后就有12行。自然连接的语法如下:

SELECT * FROM
	( SELECT id, score AS 'MATH' FROM score WHERE subject = 'MATH' ) AS t1
	NATURAL JOIN ( SELECT id, score AS 'ENGLISH' FROM score WHERE SUBJECT = 'ENGLISH' ) AS t2
	NATURAL JOIN ( SELECT id, score AS 'CHINESE' FROM score WHERE SUBJECT = 'CHINESE' ) AS t3

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

3.使用union拼接

union:会将两个结果集进行并集处理,不包括重复的行;
union all:对两个结果集进行并集处理,包括重复行。

日常开发中,能使用union all就使用union all

SELECT id,score AS 'MATH',0 AS 'ENGLISH',0 AS 'CHINESE' FROM score WHERE subject = 'MATH';

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

(SELECT id,score AS 'MATH',0 AS 'ENGLISH',0 AS 'CHINESE' FROM score WHERE subject = 'MATH')
UNION ALL
(SELECT id,0 AS 'MATH',score AS 'ENGLISH',0 AS 'CHINESE' FROM score WHERE subject = 'ENGLISH')
UNION ALL
(SELECT id,0 AS 'MATH',0 AS 'ENGLISH',score AS 'CHINESE' FROM score WHERE subject = 'CHINESE');

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

此时,我们发现目前的sql查询出来会有很多重复的行,但由于其他科目没有的数据都是0,我们可以根据id进行分组,然后sum()聚合相加一下,这样就能得到我们想要的结果

select id,SUM(MATH) AS 'MATH',SUM(ENGLISH) AS 'ENGLISH',SUM(CHINESE)AS CHINESE from (
(SELECT id,score AS 'MATH',0 AS 'ENGLISH',0 AS 'CHINESE' FROM score WHERE subject = 'MATH')
UNION ALL
(SELECT id,0 AS 'MATH',score AS 'ENGLISH',0 AS 'CHINESE' FROM score WHERE subject = 'ENGLISH')
UNION ALL
(SELECT id,0 AS 'MATH',0 AS 'ENGLISH',score AS 'CHINESE' FROM score WHERE subject = 'CHINESE')) t
GROUP BY id

以上都是列转行,反过来思路也大致一样就可以实现从行转列

SELECT id, 'MATH' subject, MATH score FROM products WHERE MATH IS NOT NULL
UNION
SELECT id, 'ENGLISH' subject, ENGLISH score FROM products WHERE ENGLISH IS NOT NULL
UNION
SELECT id, 'CHINESE' subject, CHINESE score FROM products WHERE CHINESE IS NOT NULL;

4.经典sum+if

思路:由多行变为一行,自然而然的就要想要对id进行groupby聚合,在此基础上,我们还需要根据课程名词去筛选课程成绩,因此还需要再添加一个if函数作为筛选(用case when)也可以,如果if符合条件,就设置本课程的分数,如果不符合条件,就设置为null,最后我们再通过一个sum聚合函数提取成绩即可

SELECT id,  
      if(subject='MATH', score, NULL) as `MATH`,  
      if(subject='ENGLISH', score, NULL) as `ENGLISH`, 
      if(subject='CHINESE', score, NULL) as `CHINESE`
FROM score 

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

该步骤与上面union中自己设置0有异曲同工之妙,只不过这一次是通过if判断自动的设置为null,我们只需要在此基础上,对id进行分组,再添加一个sum聚合一下就可以实现我们的需求

SELECT id,  
      sum(if(subject='MATH', score, NULL)) as `MATH`,  
      sum(if(subject='ENGLISH', score, NULL)) as `ENGLISH`, 
      sum(if(subject='CHINESE', score, NULL)) as `CHINESE`
FROM score 
GROUP BY id 

ㅤㅤㅤㅤ ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ在这里插入图片描述

### 回答1: c 调用 dll demo 是指使用 C 语言编写程序,调用一个动态链接库(DLL)示例。动态链接库是一种包含可供其他程序调用的函数和资源的文件。通过调用 DLL,C 程序可以使用 DLL 中提供的功能,实现各种功能扩展。 首先,我们需要使用 C 语言编写一个调用 DLL 的程序。在程序中,我们需要包含 DLL 的头文件,并声明需要调用的函数的原型。然后,我们通过调用 LoadLibrary 函数加载 DLL 文件,并使用 GetProcAddress 函数获取 DLL 中需要调用的函数地址。最后,我们可以通过调用获取的函数地址来调用 DLL 中的函数。 例如,我们创建一个名为 main.c 的文件,其中包含以下代码: ```c #include <stdio.h> #include <windows.h> typedef int (*MY_DLL_FUNC)(int); // 定义函数指针类型,用于存储 DLL 中的函数地址 int main() { HMODULE hDll = LoadLibrary("demo.dll"); // 加载 DLL 文件 if (hDll == NULL) { printf("无法加载 DLL 文件。\n"); return -1; } MY_DLL_FUNC myFunc = (MY_DLL_FUNC)GetProcAddress(hDll, "my_function"); // 获取函数地址 if (myFunc == NULL) { printf("无法找到函数。\n"); return -1; } int result = myFunc(10); // 调用函数 printf("DLL 函数返回值为:%d\n", result); FreeLibrary(hDll); // 释放 DLL return 0; } ``` 在上述代码中,我们加载了一个名为 demo.dll 的 DLL 文件,并从中获取了名为 my_function 的函数的地址。然后,我们将参数 10 传递给 my_function,并打印其返回值。 编译并运行上述代码后,即可成功调用 DLL 中的函数,并获得对应的结果。这样,我们就实现了通过 C 调用 DLL 的示例。 需要注意的是,实际的 DLL 文件中的函数名和参数类型可能会有所不同,需要根据具体情况进行修改。另外,在使用完成后,需要使用 FreeLibrary 函数释放已加载的 DLL。 ### 回答2: 调用dll demo 是指在编程中使用动态链接库(Dynamic Link Library)来实现某种功能。DLL是一种可供多个程序共享使用的库文件,其中包含一些函数和数据,通过调用这些函数可以实现一些特定的操作。下面是一个简单的调用dll demo的示例: 首先,我们需要确定要调用的dll文件的名称和路径。通常,dll文件需要与程序在同一目录下,或者在系统的搜索路径中。 接下来,在程序中引入dll文件。这可以通过使用import关键字或者使用专门的函数来实现。 然后,我们需要确定要调用的函数的名称和参数。我们可以通过查看dll文件的文档或者使用一些工具来获取这些信息。一旦确定了函数的名称和参数,我们就可以使用这个函数来实现我们想要的操作。 最后,我们需要在程序中调用dll函数。这可以通过使用函数名称和参数来实现。调用dll函数的过程中,我们需要注意参数的类型和顺序,确保和dll函数的定义一致,以免出现错误。 调用dll demo的过程中,我们需要注意一些问题。首先,确保dll文件的正确性和完整性,防止出现无法调用或者调用错误的问题。其次,我们需要合理处理dll函数返回的结果,以确保程序的正确运行。此外,还需要注意程序的兼容性和可移植性,以便在不同的平台和环境中都能够正常运行。 总之,调用dll demo 是一种常见的编程技术,通过使用动态链接库可以方便地实现一些功能。在使用过程中,我们需要明确dll文件的名称和路径,引入dll文件,确定要调用的函数和参数,最后在程序中调用dll函数。同时,我们还需要注意dll文件的正确性和完整性,处理函数返回的结果,并保证程序的兼容性和可移植性。 ### 回答3: C 调用 DLL demo 是指在 C 语言中调用动态链接库(DLL)的示例程序。DLL 是一种包含可被共享和重复使用的代码和数据的文件,它可以被不同的程序同时使用,从而提高代码的重用性和灵活性。 在 C 语言中,调用 DLL 需要使用特定的函数和约定。首先,需要在程序中包含 DLL 的头文件,其中包含了 DLL 中导出函数的声明。接下来,在代码中使用提供的函数名来调用 DLL 中的函数。 具体的示例程序可能如下: ``` #include <stdio.h> #include <windows.h> // 声明 DLL 中的函数 typedef int (*AddFunction)(int, int); int main() { HINSTANCE hDll; // DLL的句柄 AddFunction add; // 对应 DLL 中的函数指针 // 加载 DLL hDll = LoadLibrary("demo.dll"); if (hDll != NULL) { // 获取 DLL 中的函数地址 add = (AddFunction)GetProcAddress(hDll, "Add"); if (add != NULL) { int result = add(3, 5); printf("The result is: %d\n", result); } else { printf("Failed to find the 'Add' function in the DLL.\n"); } // 卸载 DLL FreeLibrary(hDll); } else { printf("Failed to load the DLL.\n"); } return 0; } ``` 上述示例代码中,首先使用 `LoadLibrary` 函数加载 DLL,然后使用 `GetProcAddress` 函数获取 DLL 中的函数地址,再通过函数指针调用 DLL 中的函数。最后,使用 `FreeLibrary` 函数卸载 DLL。 当运行该示例程序时,会调用 DLL 中的 `Add` 函数,该函数接受两个整数参数并返回它们的和。程序输出结果为两个整数相加的和。 需要注意的是,上述示例中的函数名和参数类型需要根据实际情况进行修改。另外,确保 DLL 文件与程序在同一目录下或者可以通过正确的路径访问到它,以便成功加载 DLL。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

楚生辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值