【问题标题】:How to transform all the values in a SQL table into a single row with multiple columns如何将 SQL 表中的所有值转换为具有多列的单行
【发布时间】:2021-12-21 10:07:44
【问题描述】:

我需要创建下表的视图

Student Marks
James 500
Jack 200
Jimmy 100

变成这样的

Student_1 Marks_1 Student_2 Marks_2 Student_3 Marks_3
James 500 Jack 200 Jimmy 100

我是 SQL 新手,我正在集思广益如何做到这一点,但我无法弄清楚。任何帮助将不胜感激,谢谢。

【问题讨论】:

  • 这类问题已经回答过很多次了。有关过去答案的列表,请参阅 stackoverflow.com/questions/tagged/mysql+pivot-table
  • 另外,您实际上很少需要在 sql 中进行数据透视(尤其是如果您是 sql 新手,您可能会高估何时需要这样做)。如果你例如只想并排显示这些学生,例如在网页上,通常的方法是调整生成代码(例如您的 php 脚本)。
  • @Solarflare 我想我应该更好地重新表述我的问题(我现在要编辑它)。我需要从第一个表创建一个看起来像给定的第二个表的视图。我正在尝试查看如何完成此操作的示例,但我没有找到任何示例。
  • @BillKarwin 我环顾四周,但找不到这样的东西,我发现的只是唯一键是新行的表,但我只需要一行多列,如上所示。如果您已经知道类似示例的位置,那将非常有帮助。谢谢。
  • How can I return pivot table output in MySQL? 应该涵盖在 mysql 中生成数据透视表的可用方法。您必须根据自己的情况进行调整,例如如果您不希望 “唯一键是新行”,请不要使用 group by。如果您有未知数量的学生(因此:列),请选择/调整例如this answer 在链接的问题中(虽然不能作为视图)。但是再重复一遍:在 sql 中生成该枢轴实际上可能不是您的任务,我会先对其进行三重检查。

标签: mysql sql database pivot-table sql-view


【解决方案1】:

这是您的案例的示例。你可以使用PREPARE语句

SELECT CONCAT( "SELECT ",
     GROUP_CONCAT(
     CONCAT('"',Student,'"'),CONCAT(' AS "Student_',@Nr:=@Nr+1,'", ')
    ,CONCAT('"',Marks,'"'),CONCAT(' AS "Marks_',@Nr,'" ')  SEPARATOR ' , ')
    ," FROM DUAL;") INTO @myquery
FROM stud
CROSS JOIN (SELECT @Nr:=0) as Init
ORDER BY Marks DESC;


## ONLY FOR DEBUG
SELECT @myquery;

PREPARE stmt FROM @myquery;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

样本

MariaDB [Bernd]> SELECT * from stud;
+----+---------+-------+
| id | Student | Marks |
+----+---------+-------+
|  1 | James   |   500 |
|  2 | Jack    |   200 |
|  3 | Jimmy   |   100 |
+----+---------+-------+
3 rows in set (0.01 sec)

MariaDB [Bernd]> SELECT CONCAT( "SELECT ",
    ->  GROUP_CONCAT(
    ->  CONCAT('"',Student,'"'),CONCAT(' AS "Student_',@Nr:=@Nr+1,'", ')
    -> ,CONCAT('"',Marks,'"'),CONCAT(' AS "Marks_',@Nr,'" ')  SEPARATOR ' , ')
    -> ," FROM DUAL;") INTO @myquery
    -> FROM stud
    -> CROSS JOIN (SELECT @Nr:=0) as Init
    -> ORDER BY Marks DESC;
Query OK, 1 row affected (0.00 sec)
    
MariaDB [Bernd]> ## ONLY FOR DEBUG
MariaDB [Bernd]> SELECT @myquery;
+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| @myquery                                                                                                                                                 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------+
| SELECT "James" AS "Student_1", "500" AS "Marks_1"  , "Jack" AS "Student_2", "200" AS "Marks_2"  , "Jimmy" AS "Student_3", "100" AS "Marks_3"  FROM DUAL; |
+----------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
    
MariaDB [Bernd]> PREPARE stmt FROM @myquery;
Query OK, 0 rows affected (0.00 sec)
Statement prepared

MariaDB [Bernd]> EXECUTE stmt;
+-----------+---------+-----------+---------+-----------+---------+
| Student_1 | Marks_1 | Student_2 | Marks_2 | Student_3 | Marks_3 |
+-----------+---------+-----------+---------+-----------+---------+
| James     | 500     | Jack      | 200     | Jimmy     | 100     |
+-----------+---------+-----------+---------+-----------+---------+
1 row in set (0.00 sec)

MariaDB [Bernd]> DEALLOCATE PREPARE stmt;
Query OK, 0 rows affected (0.00 sec)

MariaDB [Bernd]> 

【讨论】:

  • 完美!但是如果我们想使用 GROUP BY 语句,它是如何工作的。例如,如果我们添加了另一列,那么我们有:id、student、marks、subject。例如,詹姆斯和杰克属于“英语”的学科,而吉米的学科是“数学”。您将如何重写此语句并使用 GROUP BY 主题,这将在两行中显示两个主题的结果?谢谢你的期待
  • 你能给我你想要的结果吗?
  • 结果应该是两行,一行是英文,另一行是'数学'
  • @Barbaros Özhan - 非常感谢
猜你喜欢
  • 1970-01-01
  • 2021-10-22
  • 2012-03-19
  • 1970-01-01
  • 2017-02-07
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多