MySQL将列标题分为单列,第二列为值

MySQL将列标题分为单列,第二列为值,mysql,sql,cursors,Mysql,Sql,Cursors,我目前有一个表格,以 从XYZ中选择* 我希望数据总共有4列,如下所示: Date | Brand | GameName | Value 2017 | xxxxx | Game1 | 1234567.89 2017 | xxxxx | Game2 | 98.7654321 2017 | xxxxx | Game3 | 12345987.65 这样做的原因是为了使数据更容易过滤以找到特定的值 我已经尝试了很多其他的建议,但还没有成功 例如,concat组 一个可行的建议是使用UNIONAL

我目前有一个表格,以

从XYZ中选择*

我希望数据总共有4列,如下所示:

Date | Brand | GameName | Value

2017 | xxxxx | Game1 | 1234567.89

2017 | xxxxx | Game2 | 98.7654321

2017 | xxxxx | Game3 | 12345987.65
这样做的原因是为了使数据更容易过滤以找到特定的值

我已经尝试了很多其他的建议,但还没有成功

例如,concat组

一个可行的建议是使用UNIONALL,但是我需要一个动态查询 因为该表将在将来继续添加到


目前,我正在尝试设置一个游标来执行此操作。

如果您的表将继续具有新列,那么无论使用哪个查询,您都必须首先从INFORMATION_SCHEMA.table中获取所有列,以下是一种方法:

获取具有%Game%模式的所有列名 使用UNION或任何其他查询来获取输出 以下是一个例子:

SELECT `COLUMN_NAME` 
FROM `INFORMATION_SCHEMA`.`COLUMNS` 
WHERE `TABLE_SCHEMA`='db_name' 
    AND `TABLE_NAME`='table'
    AND COLUMN_NAME LIKE '%Game%';
现在,从该查询的输出,构造一个动态联合查询,例如:

SELECT Date, Brand, `<column>`, Value
FROM table

UNION

SELECT Date, Brand, `<column>`, Value
FROM table

您可以结合使用聚合来执行unpivot,以生成所需的输出。请注意,您要为每个游戏计算的值与相应游戏列的总和一致。这是因为你说所有其他值都是零

SELECT
    Date,
    MAX(CASE WHEN Game1 <> 0 THEN Brand END) AS Brand,
    'Game1' AS GameName,
    SUM(Game1) AS Value
FROM yourTable
GROUP BY Date
UNION ALL
SELECT
    Date, MAX(CASE WHEN Game2 <> 0 THEN Brand END), 'Game2', SUM(Game2)
FROM yourTable
GROUP BY Date
UNION ALL
SELECT
    Date, MAX(CASE WHEN Game3 <> 0 THEN Brand END), 'Game3', SUM(Game3)
FROM yourTable
GROUP BY Date
此处演示:

这应该行得通

select Date, Brand, 'Game1', Game1 where Game1 is not null
UNION ALL
select Date, Brand, 'Game2' Game2 where Game2 is not null
UNION ALL
select Date, Brand, 'Game3' Game3 where Game3 is not null

您可以将其保存为视图,并直接查询结果

这些虚线是什么?它们是否真的是破折号,或者是否存在其他内容,例如空字符串或null?在表中,它们仅为0。在这个问题中,有人问了类似的问题。这里的关键字是Transpanding或unpivot。如果没有任何东西可以连接到我的最终表中,我如何进入它?您将迭代第一个查询的结果集,并为最终结果创建联合查询。只是第一次查询中的一行的值。MySQL不支持CTE,但在任何情况下,您的数据都与问题中的数据不匹配,请注意上面的注释。在这种情况下,我将删除CTE并重新构造数据,这样可以工作,但问题是我需要一个动态查询
select Date, Brand, 'Game1', Game1 where Game1 is not null
UNION ALL
select Date, Brand, 'Game2' Game2 where Game2 is not null
UNION ALL
select Date, Brand, 'Game3' Game3 where Game3 is not null