如何将数据从一列排序到多列

  • 本文关键字:一列 排序 数据 sql oracle
  • 更新时间 :
  • 英文 :


如果我在Oracle表中有一列数据

A1
A2
C1
D2
B1
C2
B3
D4
A3, and so on

如何使用脚本对更多列中的数据进行排序

A1 B1 C1 D2
A2 B3 C2 D4
A3

这里有一个选择。

样本数据:

SQL> select * from test;
CO
--
A1
A2
C1
D2
B1
C2
B3
D4
A3
9 rows selected.

查询:

  • tempcte返回源表中每一行的行号
  • temp2计算"组";(4列组成一行),而rn2表示该行中每列的位置(从位置1到位置4)
  • final查询只返回每个"新创建"中的每个组的一个列值。列(最多4列)。

SQL> with temp as
2    (select col,
3            row_number() over (order by rowid) rn
4     from test
5    ),
6  temp2 as
7    (select col,
8            ceil(rn / 4) grp,
9            case when mod(rn - 4, 4) = 0 then 4
10                 when mod(rn - 4, 3) = 0 then 3
11                 when mod(rn - 4, 2) = 0 then 2
12                 else 1
13            end rn2
14     from temp
15    )
16  select min(case when rn2 = 1 then col end) c1,
17         min(case when rn2 = 2 then col end) c2,
18         min(case when rn2 = 3 then col end) c3,
19         min(case when rn2 = 4 then col end) c4
20  from temp2
21  group by grp;
C1 C2 C3 C4
-- -- -- --
C1 A2 A1 D2
B1 C2 B3 D4
A3
SQL>

我认为这是不可能的;汇总的结果和你展示的完全一样。请记住,您正在处理结构化数据和关系。

在您的示例中,您显示了第一个元组:
A1 B1 C1 D2

然而,在真实的表中,A1 B1 C1 D2都不相关(水平)。

您可以在一个SELECT子句中使用多个CASE语句来确定哪个"result-set"列显示数据。这将为您提供类似于以下结果:

A.   B.   C.   D.   
-------------------
A1.  null null null
A2.  null null null
null null C1.  null
...

将由您的程序稍后读取结果并删除空值。

select 
case value when 0 then 1 else null end as A,
case value when 1 then 1 else null end as B,
case value when 2 then 1 else null end as C,
case value when 3 then 1 else null end as D,
case value when 4 then 1 else null end as E
from events

"drawback"我看到的是你必须定义硬编码列,这可能是可接受的,也可能是不可接受的(根据您的用例)

SQL fiddle: http://sqlfiddle.com/#!9/63dd887

这最好在中间层应用程序(Java, c#, PHP等)中完成,但如果您想在SQL中完成,您可以PIVOT:

SELECT a, b, c, d
FROM   (
SELECT value,
MOD(ROWNUM - 1, 4) AS col,
CEIL(ROWNUM/4) AS rw
FROM   table_name
)
PIVOT(MAX(value) FOR col IN (0 AS A, 1 AS B, 2 AS C, 3 AS D))
ORDER BY rw

对于样本(随机)数据:

CREATE TABLE table_name (value) AS
SELECT CHR(64+FLOOR(DBMS_RANDOM.VALUE(1,5))) || FLOOR(DBMS_RANDOM.VALUE(1,5))
FROM   DUAL
CONNECT BY LEVEL <= 42;

可能输出:

<表类>BCDtbody><<tr>B2D1C4D3C3B3C2A1A3B2B4D1A2B4D1B1C3D2C4D4C4D1D4B3C2C3A4C1D3A4B4A3A4C3C1A2B2C4A2B3D1C2

最新更新