我想选择数据库中的所有行,但希望它们以倒序排列。意思是,我想将第一列数据用作新实体,将当前实体用作第一列。我想你明白我的意思
这是一个例子
id | name | marks ------------------------------- 1 | Ram | 45 -------------------------------- 2 | Shyam | 87
至
id | 1 | 2 | ---------------------------- Name | Ram | Shyam | ---------------------------- Marks | 45 | 87 |
使用固定的已知列,这里是做这的方法(我将表命名为“ grades”是自由的):
创建并执行不同查询的并集。
由于您需要实际数据作为列标题,因此联合的第一部分如下所示:
SELECT 'id', '1', '2', ....
仅该查询将复制结果,因此我们需要通过添加告诉MySQL我们需要有0行LIMIT 0, 0。
LIMIT 0, 0
联合的第一行将包含'Name'和表的“名称”列中的所有数据。要获得该行,我们需要一个查询,例如:
'Name'
SELECT 'Name', (SELECT Name FROM grades LIMIT 0, 1), (SELECT Name FROM grades LIMIT 1, 1), (SELECT Name FROM grades LIMIT 2, 1), ...
使用相同的逻辑,我们的第二行将如下所示:
SELECT 'Marks', (SELECT Marks FROM grades LIMIT 0, 1), (SELECT Marks FROM grades LIMIT 1, 1), (SELECT Marks FROM grades LIMIT 2, 1), ...
我们需要从MySQL产生一行,例如:
SELECT 'id', '1', '2', ... LIMIT 0, 0;
为了获得这一行,我们将使用CONCAT()和GROUP_CONCAT()函数:
SELECT 'id', (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades) LIMIT 0, 0;
我们将把该行存储到一个新变量中:
SET @header = CONCAT('SELECT \'id\', ', (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades), ' LIMIT 0, 0');
我们需要创建两个如下查询:
由于我们事先不知道原始表中有多少行,因此我们将使用变量来生成不同的LIMIT x, 1语句。可以使用以下方法生产它们:
LIMIT x, 1
SET @a = -1; SELECT @a:=@a+1 FROM grades;
使用此代码段,我们可以创建子查询:
SELECT GROUP_CONCAT( CONCAT(' (SELECT name FROM grades LIMIT ', @a:=@a+1, ', 1)') ) FROM grades
我们将把它与第一列数据(这是第二列的名称)一起放入变量名@ line1中:
SET @a = -1; SET @line1 = CONCAT( 'SELECT \'Name\',', ( SELECT GROUP_CONCAT( CONCAT(' (SELECT Name FROM grades LIMIT ', @a:=@a+1, ', 1)') ) FROM grades ));
通过遵循相同的逻辑,第二行将是:
SET @a := -1; SET @line2 = CONCAT( 'SELECT \'Marks\',', ( SELECT GROUP_CONCAT( CONCAT(' (SELECT Marks FROM grades LIMIT ', @a:=@a+1, ', 1)') ) FROM grades ));
现在,我们的三个变量包含:
@header: SELECT 'id', '1', '2' LIMIT 0, 0 @line1: SELECT 'Name', (SELECT Name FROM grades LIMIT 0, 1), (SELECT name FROM grades LIMIT 1, 1) @line2: SELECT 'Marks', (SELECT Marks FROM grades LIMIT 0, 1), (SELECT marks FROM grades LIMIT 1, 1)
我们只需要使用创建最终变量CONCAT(),将其准备为新查询并执行即可:
CONCAT()
SET @query = CONCAT('(', @header, ') UNION (', @line1, ') UNION (', @line2, ')' ); PREPARE my_query FROM @query; EXECUTE my_query;
(供测试和参考):
SET @header = CONCAT('SELECT \'id\', ', (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades), ' LIMIT 0, 0'); SET @a = -1; SET @line1 = CONCAT( 'SELECT \'Name\',', ( SELECT GROUP_CONCAT( CONCAT(' (SELECT Name FROM grades LIMIT ', @a:=@a+1, ', 1)') ) FROM grades )); SET @a := -1; SET @line2 = CONCAT( 'SELECT \'Marks\',', ( SELECT GROUP_CONCAT( CONCAT(' (SELECT Marks FROM grades LIMIT ', @a:=@a+1, ', 1)') ) FROM grades )); SET @query = CONCAT('(', @header, ') UNION (', @line1, ') UNION (', @line2, ')' ); PREPARE my_query FROM @query; EXECUTE my_query;
输出:
+ ------- + ------ + ------- + | id | 1 | 2 | + ------- + ------ + ------- + | 姓名| 拉姆| Shyam | | 商标| 45 | 87 | + ------- + ------ + ------- + 设置2行(0.00秒)
我仍然不确定为什么需要将行转换为列,并且我确定我提出的解决方案并不是最佳的解决方案(就性能而言)。
您甚至可以使用我的解决方案作为开始,并使之适应于不知道表列名称(和行数)的通用解决方案information_schema。COLUMNS作为来源,但我想这太过分了。
information_schema
COLUMNS
我坚信最好将原始表放入数组中,然后旋转该数组,从而以所需的格式获取数据。