iT邦幫忙

0

oracle 反覆排序該怎麼做

我想呈現的是反覆排序從A-Z再從A-Z這樣子的資料,但是 ORDER BY 會將相同的資料歸為一類,所以只會呈現AABBCCDD這樣子的資料,想請教有什麼方式可以達成反覆排序?

原始需求:組數目前是2,下次...這次做得出來再說
要取出前2組ABCDEF...WXYZ的話,換言之我要取得A的前2筆+B的前2筆+C的前2筆+...
而且不能按AABBCC來排,要以ABCDEF...WXYZABCDEF...WXYZ排出2組共52筆,多的就不要了

ex:
姓名 類別 ...
王一  A  ...
任五  B  ...
.   .  ...
.   .  ...
曾山  Y  ...
同大  Z  ...
本山  A  ...
林依  B  ...
.   .  ...
.   .  ...
安田  Y  ...
瑞凡  Z  ...

如果真的不行,妥協的方案是AABBCC...XXYYZZ
3組就是AAABBBCCCDDD...XXXYYYZZZ
一樣是多的就不要

看更多先前的討論...收起先前的討論...
小魚 iT邦新手 2 級 ‧ 2017-06-09 22:44:44 檢舉
我倒是沒聽過這種排序,為什麼要這樣做?
新鮮肝 iT邦新手 5 級 ‧ 2017-06-09 23:50:28 檢舉
我也不知道為什麼客戶要求要這樣子做...
Albert iT邦高手 1 級 ‧ 2017-06-10 02:25:57 檢舉
這很簡單
這不是反覆排序
這是分組排序
Albert iT邦高手 1 級 ‧ 2017-06-10 04:44:31 檢舉
王一  A  ...
....
本山  A 
因為這兩個屬於不同組
所以要先指定分組, 也可以用順序分組, 依據日期第一次的放第一組,
新鮮肝 iT邦新手 5 級 ‧ 2017-06-10 08:35:25 檢舉
資料庫沒有存日期的資料,而且沒有可以優先於 A至Z的分組條件
DRDER BY 其他欄位,類別,雖然 類別的確是有順序,但是只會如下的順序吧
王一  A  a'
同山  D  a'
林本  B  b'
Albert iT邦高手 1 級 ‧ 2017-06-10 09:32:56 檢舉
換言之我要取得A的前2筆+B的前2筆+C的前2筆
請問前兩筆的定義
是"INSERT " 先後 ? 還是 ?
新鮮肝 iT邦新手 5 級 ‧ 2017-06-10 10:14:10 檢舉
其實客戶沒有指定,所以先後或隨機都行。

2 個回答

1
一級屠豬士
iT邦新手 4 級 ‧ 2017-06-10 21:47:15
在家懶得開Oracle, 用Postgresql代替.產生測試資料有些不同.
查詢部份也自己改成Oracle的函數就可以了.
create table g170610 (
  id serial primary key
, gname text not null
, gtype CHAR(1) not null
);

-- 產生 26 x 4 = 104 筆, 亂數排序
insert into g170610 (gname, gtype)
select n || m::text
     , chr(64+m)
  from (values ('趙'),('錢'),('孫'),('李')) a(n)
     , generate_series(1, 26) g(m)
 order by random();

select *
  from g170610;

 id  | gname | gtype 
-----+-------+-------
   1 | 趙3   | C
   2 | 錢19  | S
   3 | 李19  | S
...
 102 | 孫1   | A
 103 | 李1   | A
 104 | 孫21  | U
(104 筆資料列)
---------------------
with t1 as (
select gname
     , gtype
     , row_number() over (partition by gtype) as rn
  from g170610
)
select gname
     , gtype
  from t1
 where rn <= 2
 order by rn, gtype;

 gname | gtype 
-------+-------
 孫1   | A
 孫2   | B
 孫3   | C
 孫4   | D
 錢5   | E
 孫6   | F
 錢7   | G
 錢8   | H
 錢9   | I
 李10  | J
 孫11  | K
 孫12  | L
 錢13  | M
 錢14  | N
 李15  | O
 趙16  | P
 孫17  | Q
 錢18  | R
 李19  | S
 趙20  | T
 趙21  | U
 李22  | V
 李23  | W
 孫24  | X
 李25  | Y
 趙26  | Z
 李1   | A
 李2   | B
 趙3   | C
 趙4   | D
 趙5   | E
 李6   | F
 孫7   | G
 趙8   | H
 趙9   | I
 孫10  | J
 趙11  | K
 趙12  | L
 李13  | M
 孫14  | N
 錢15  | O
 孫16  | P
 趙17  | Q
 李18  | R
 趙19  | S
 孫20  | T
 李21  | U
 孫22  | V
 趙23  | W
 李24  | X
 趙25  | Y
 李26  | Z
(52 筆資料列)
 
----
要三組 就  rn <= 3

幸運叔祝大家幸運喔

新鮮肝 iT邦新手 5 級 ‧ 2017-06-12 15:38:21 檢舉

在測試了幾次row_number、partition by和order by未果後,礙於時程關係,我決定先採用海綿寶寶的方法,不過我還是會努力摸索的...畢竟如果能成功的話,更改起來會比較容易。

0
海綿寶寶
iT邦超人 1 級 ‧ 2017-06-12 09:11:43
CREATE TABLE tbldummy
(
 dname varchar2(4),
 dtype varchar2(1)
);

INSERT INTO tbldummy VALUES ('N001', 'A');
INSERT INTO tbldummy VALUES ('N002', 'B');
INSERT INTO tbldummy VALUES ('N003', 'C');
....
INSERT INTO tbldummy VALUES ('N026', 'Z');
INSERT INTO tbldummy VALUES ('N027', 'A');
INSERT INTO tbldummy VALUES ('N028', 'B');
INSERT INTO tbldummy VALUES ('N029', 'C');
....
INSERT INTO tbldummy VALUES ('N052', 'Z');
INSERT INTO tbldummy VALUES ('N053', 'A');
INSERT INTO tbldummy VALUES ('N054', 'B');
INSERT INTO tbldummy VALUES ('N055', 'C');
....
INSERT INTO tbldummy VALUES ('N078', 'Z');
(SELECT * FROM tbldummy WHERE dtype='A' AND ROWNUM < 3) UNION
(SELECT * FROM tbldummy WHERE dtype='B' AND ROWNUM < 3) UNION
(SELECT * FROM tbldummy WHERE dtype='C' AND ROWNUM < 3) UNION
....
(SELECT * FROM tbldummy WHERE dtype='Z' AND ROWNUM < 3);
新鮮肝 iT邦新手 5 級 ‧ 2017-06-12 15:37:22 檢舉

感謝你。

我要發表回答

立即登入回答