我可以根据不同列中显示的值来更改SQL表中的列顺序吗?

问题描述

我有一个看起来像这样的表:

Column1 | Column2 | Column3| Column4
    4   |    3    |    2   |    1
    2   |    1
    3   |    2    |    1

我想翻转列,以使1始终从列1开始,然后其余值向右移动。像这样:

Column1 | Column2 | Column3 | Column4
    1   |    2    |    3    |   4
    1   |    2    
    1   |    2    |    3

这是一个示例表。实际表是公司的层次结构,因此例如1 = CEO,2 = SVP。 1始终是相同的名称,但是随着数字的增加(命令链中的位置越低),该级别中的名称就越多。我希望寻找一个自动解决方案,寻找1,使第一列,然后填充列。我很努力,因为1表示的值在不同的列中,所以我不能只更改列的顺序。

我能够使用VBA完成此操作,但我希望将其保留在sql中。

到目前为止,我没有任何有用的代码

解决方法

您可以使用Case表达式:

WITH CTE1 AS
(SELECT 4 AS COL1,3  AS COL2,2 AS COL3,1 AS COL4 FROM DUAL
UNION ALL
SELECT 2,1,NULL,NULL FROM DUAL
UNION ALL
SELECT 3,2,NULL FROM DUAL
)
SELECT CASE WHEN COL1 <> 1 THEN 1 ELSE COL1 END AS COL1,CASE WHEN COL2 <> 2 THEN 2 ELSE COL2 END AS COL2,CASE WHEN COL3 <> 3 THEN 3 ELSE COL3 END AS COL3,CASE WHEN COL4 <> 4 THEN 4 ELSE COL4 END AS COL4
FROM CTE1;
,

您可以应用一些CASEes检查所有可能性,这是假设缺失数据为NULL:

COALESCE(col4,col3,col2,col1) AS c1,CASE
    WHEN col4 IS NOT NULL THEN col3
    WHEN col3 IS NOT NULL THEN col2
    WHEN col2 IS NOT NULL THEN col1
END AS c2,CASE
    WHEN col4 IS NOT NULL THEN col2
    WHEN col3 IS NOT NULL THEN col1
END AS c3,CASE
    WHEN col4 IS NOT NULL THEN col1
END AS c4
,

您要对值进行排序。通用SQL解决方案将使用:

select max(case when seqnum = 1 then col end) as col1,max(case when seqnum = 2 then col end) as col2,max(case when seqnum = 3 then col end) as col3,max(case when seqnum = 4 then col end) as col4
from (select col1,col4,col,row_number() over (order by col) as seqnum
      from ((select col1 as col,1 as which,col1,col4 from t) union all
            (select col2 as col,2 as which,col4 from t) union all
            (select col3 as col,3 as which,col4 from t) union all
            (select col4 as col,4 as which,col4 from t)
           ) t
      where col is not null
     ) t
group by col1,col4;

在支持横向联接的数据库中,这会更简单。而且每行上的唯一ID也会有所帮助。