在sql select上加入,重命名和清除(压缩)列

时间:2018-03-16 10:23:12

标签: mysql sql

在excel上,我从MySQL服务器查询表,然后修改数据显示方式。我正在改变SQL,所以数据已经是我想要的方式,其中一部分是这样的:

有25列名为operator1-5lot1-5(1-5在1到5中),如下所示:

operator1lot1operator2lot1operator3lot1operator4lot1operator5lot1operator1lot2operator2lot2operator3lot2operator4lot2operator5lot2operator1lot3operator2lot3operator3lot3operator4lot3operator5lot3operator1lot4,{ {1}},operator2lot4operator3lot4operator4lot4operator5lot4operator1lot5operator2lot5operator3lot5,{{1 }}

operator4lot5总是一个值,然后每个下一个运算符都可以有一个值,如果后面的那个也有(如果operator5lot5有一个值那么运算1到3的批次1)和相同的方法到operator1lotX(如果operator1lot1有一个值,那么第1和第2手的运算符1,但并不意味着第1和第2手的运算符2到5都有一个值。)

(没有值意味着它是operator4lot1

目前在excel上operator1lot3所有25列,如果有空格,则将值加入左侧(如果NULLSELECT,则operator2lot3的值为移动到那里,向左)然后我从表的右侧向左删除空的列(其所有值NULL),最后我从左到右重命名列至operator3lot3NULL(2 <= x <= 25)。

这是一个更好地解释它的例子。数据库表如下所示:

MySQL table

在Excel上,它格式化为:

Excel table

我的问题是,是否可以直接格式化SQL中的数据。我不知道很多SQL命令,所以我能找到的最接近我不想做的就是CONCAT_WSAS

2 个答案:

答案 0 :(得分:1)

正如我之前所说,使用生成实际Excel文件的脚本可能更容易。

无论如何,我确实有一个解决方案,它看起来并不漂亮,我不确定这是理想的方法,但现在就去了。

SELECT 
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 0 
        THEN substring_index(`combinedCols`,',',1 )
        ELSE NULL 
    END AS col1,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 1 
        THEN substring_index(substring_index(`combinedCols`,',',2 ),',',-1) 
        ELSE NULL 
    END AS col2,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 2 
        THEN substring_index(substring_index(`combinedCols`,',',3 ),',',-1)
        ELSE NULL 
    END AS col3,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 3 
        THEN substring_index(substring_index(`combinedCols`,',',4 ),',',-1)
        ELSE NULL 
    END AS col4,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 4 
        THEN substring_index(substring_index(`combinedCols`,',',5 ),',',-1)
        ELSE NULL 
    END AS col5,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 5 
        THEN substring_index(substring_index(`combinedCols`,',',6 ),',',-1)
        ELSE NULL 
    END AS col6,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 6 
        THEN substring_index(substring_index(`combinedCols`,',',7 ),',',-1)
        ELSE NULL 
    END AS col7,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 7 
        THEN substring_index(substring_index(`combinedCols`,',',8 ),',',-1)
        ELSE NULL 
    END AS col8,
    CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 8 
        THEN substring_index(substring_index(`combinedCols`,',',9 ),',',-1)
        ELSE NULL 
    END AS col9
FROM 
    (SELECT CONCAT_WS(',',`col1`,`col2`,`col3`,`col4`,`col5`,`col6`,`col7`,`col8`,`col9`) AS `combinedCols` FROM `tableName`) AS `tableNameAlias`;

就我的例子而言,我只把它列为9列,但一旦你理解了我所做的事情,就不应该把它扩展到25或更多。

第1步

SELECT CONCAT_WS(',',`col1`,`col2`,`col3`,`col4`,`col5`,`col6`,`col7`,`col8`,`col9`) AS `combinedCols` FROM `tableName`

首先我们需要组合所有列,因为我们可以使用CONCAT_WS,此函数的第一个参数是我们将在这种情况下使用的粘合剂,

第2步

substring_index(`combinedCols`,',',1 )

现在我们需要使用,SUBSTRING_INDEX上以某种方式爆炸这些值,我们可以在指定的事件上分隔指定字符末尾的值。

第3步

substring_index(substring_index(`combinedCols`,',',2 ),',',-1)

在第一次出现之后,我们需要获取最后一次出现,在这种情况下,第二次出现,因此我们再次执行相同的函数,但现在使用负值-1

第4步

CASE WHEN (char_length(`combinedCols`) - char_length(replace(`combinedCols`, ',', '')) + 1) > 1

最后一部分是检查是否确实有足够的值来检查。此部分计算使用量,,如果足够执行代码,则只需设置值NULL

那么希望这能解决你的问题。

答案 1 :(得分:0)

作为示例,仅考虑前3列和前3行数据,规范化模式可能包含4或5列,如下所示:

id operator lot entry value
 1        1   1     1  117
 2        1   1     2  117 
 3        1   1     3  129 
 4        2   1     1  319
 5        2   1     2  319
 6        3   1     2  530

代理主键ID并非绝对必要,因为接下来的3列中存在令人满意的PK。