选择MYSQL行,但行为列,列为行

Sta*_*arx 3 php mysql

我想选择数据库中的所有行,但我希望它们按顺序排列.意思是,我想使用第一列数据作为新实体,并将实体作为第一列.我想你明白了我的意思

这是一个例子

id    |     name       | marks
-------------------------------
1     |    Ram         | 45
--------------------------------
2     |    Shyam       |  87
Run Code Online (Sandbox Code Playgroud)

id    |   1     |    2     |
----------------------------
Name  |  Ram    |   Shyam  |
----------------------------
Marks |  45     |    87    | 
Run Code Online (Sandbox Code Playgroud)

Ana*_*nax 16

使用固定和已知的列,这里是如何做到的(我冒昧地命名表"成绩"):

大概的概念:

创建不同查询的并集并执行它.

由于您需要实际数据作为列标题,因此联合的第一部分将如下所示:

SELECT 'id', '1', '2', ....
Run Code Online (Sandbox Code Playgroud)

单独的查询将复制结果,因此我们需要通过添加告诉MySQL我们需要有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),
    ...
Run Code Online (Sandbox Code Playgroud)

使用相同的逻辑,我们的第二行将如下所示:

SELECT 'Marks',
    (SELECT Marks FROM grades LIMIT 0, 1),
    (SELECT Marks FROM grades LIMIT 1, 1),
    (SELECT Marks FROM grades LIMIT 2, 1),
    ...
Run Code Online (Sandbox Code Playgroud)

获得标题:

我们需要从MySQL生成一行,如:

SELECT 'id', '1', '2', ... LIMIT 0, 0;
Run Code Online (Sandbox Code Playgroud)

要获得该行,我们将使用CONCAT()GROUP_CONCAT()函数:

SELECT 'id', 
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades)
LIMIT 0, 0;
Run Code Online (Sandbox Code Playgroud)

我们要将该行存储到一个新变量中:

SET @header = CONCAT('SELECT \'id\', ',
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades),
    ' LIMIT 0, 0');
Run Code Online (Sandbox Code Playgroud)

创建线条:

我们需要创建两个查询,如下所示:

SELECT 'Name',
    (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT Name FROM grades LIMIT 1, 1),
    (SELECT Name FROM grades LIMIT 2, 1),
    ...
Run Code Online (Sandbox Code Playgroud)

由于我们事先并不知道原始表中有多少行,因此我们将使用变量生成不同的LIMIT x, 1语句.它们可以使用以下方法生产:

SET @a = -1;
SELECT @a:=@a+1 FROM grades;
Run Code Online (Sandbox Code Playgroud)

使用此代码段,我们可以创建子查询:

SELECT GROUP_CONCAT(
    CONCAT(' (SELECT name FROM grades LIMIT ',
        @a:=@a+1,
        ', 1)')
    )
FROM grades
Run Code Online (Sandbox Code Playgroud)

我们将把变量名称@ line1和第一列数据(这是第二列的名称)放在一起:

SET @a = -1;
SET @line1 = CONCAT(
    'SELECT \'Name\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Name FROM grades LIMIT ',
                @a:=@a+1,
                ', 1)')
            )
        FROM grades
    ));
Run Code Online (Sandbox Code Playgroud)

按照相同的逻辑,第二行将是:

SET @a := -1;
SET @line2 = CONCAT(
    'SELECT \'Marks\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Marks FROM grades LIMIT ',
                @a:=@a+1,
                ', 1)')
            )
        FROM grades
    ));
Run Code Online (Sandbox Code Playgroud)

将它们组合在一起:

我们的三个变量现在包含:

@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)
Run Code Online (Sandbox Code Playgroud)

我们只需要使用创建最终变量CONCAT(),将其准备为新查询并执行它:

SET @query = CONCAT('(',
    @header,
    ') UNION (',
    @line1,
    ') UNION (',
    @line2,
    ')'
);

PREPARE my_query FROM @query;
EXECUTE my_query;
Run Code Online (Sandbox Code Playgroud)

整个方案:

(用于测试和参考):

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;
Run Code Online (Sandbox Code Playgroud)

输出:

+-------+------+-------+
| id    | 1    | 2     |
+-------+------+-------+
| Name  | Ram  | Shyam |
| Marks | 45   | 87    |
+-------+------+-------+
2 rows in set (0.00 sec)

结束思路:

  • 我仍然不确定为什么你需要将行转换为列,我确信我提出的解决方案不是最好的(在性能方面).

  • 您甚至可以使用我的解决方案作为开始,并使其适用于通用解决方案,其中表列名称(和行数)未知information_schema.COLUMNS作为一个来源,但我想这只是走得太远了.

  • 我坚信将原始表放入数组然后旋转该数组会更好,从而获得所需格式的数据.