給定一張表 t0,包含三個整數欄位 column1、column2、column3。要求將資料按 column1 排序後,奇數行取前半段遞增,偶數行取後半段遞增,最終交錯輸出。
| column1 | column2 | column3 |
|---|---|---|
| 11 | 12 | 13 |
| 13 | 14 | 15 |
| 21 | 22 | 23 |
| 22 | 23 | 24 |
| 12 | 13 | 14 |
| 25 | 26 | 27 |
| column1 | column2 | column3 |
|---|---|---|
| 11 | 12 | 13 |
| 21 | 22 | 23 |
| 12 | 13 | 14 |
| 22 | 23 | 24 |
| 13 | 14 | 15 |
| 25 | 26 | 27 |
column1 排序,計算總筆數 @n。@a = CEILING(@n/2) 筆放入游標 crs1(前半段,遞增)。@b = @n - @a 筆放入游標 crs2(後半段,遞增)。crs1、crs2 取資料寫入暫存表 #t。#t。CREATE TABLE t0 (column1 INT, column2 INT, column3 INT);
INSERT INTO t0 VALUES
(11,12,13), (13,14,15), (21,22,23),
(22,23,24), (12,13,14), (25,26,27);
CREATE TABLE #t (column1 INT, column2 INT, column3 INT);
DECLARE @c1 INT, @c2 INT, @c3 INT, @n INT, @a INT, @b INT;
SELECT @n = COUNT(*) FROM t0;
IF (@n % 2 = 1) SET @a = @n/2 + 1 ELSE SET @a = @n/2;
SET @b = @n - @a;
-- 前半段游標(遞增)
EXEC('DECLARE crs1 CURSOR FOR SELECT TOP ' + @a + ' * FROM t0 ORDER BY column1');
-- 後半段游標(先降序取後 @b 筆,再遞增)
EXEC('DECLARE crs2 CURSOR FOR SELECT * FROM (SELECT TOP ' + @b + ' * FROM t0 ORDER BY column1 DESC) AS b ORDER BY column1 ASC');
OPEN crs1; OPEN crs2;
WHILE @n > 0
BEGIN
IF @n % 2 = 0 -- 偶數行取前半段
BEGIN
FETCH NEXT FROM crs1 INTO @c1, @c2, @c3;
INSERT INTO #t VALUES (@c1, @c2, @c3);
END
ELSE -- 奇數行取後半段
BEGIN
FETCH NEXT FROM crs2 INTO @c1, @c2, @c3;
INSERT INTO #t VALUES (@c1, @c2, @c3);
END
SET @n = @n - 1;
END
SELECT * FROM #t;
DEALLOCATE crs1; DEALLOCATE crs2;
DROP TABLE #t; DROP TABLE t0;
使用視窗函數 ROW_NUMBER() 與 NTILE(2) 可大幅簡化:
WITH sorted AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY column1) AS rn,
NTILE(2) OVER (ORDER BY column1) AS grp
FROM t0
),
front AS (SELECT * FROM sorted WHERE grp = 1 ORDER BY rn),
back AS (SELECT * FROM sorted WHERE grp = 2 ORDER BY rn),
numbered AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY rn) AS seq FROM front
UNION ALL
SELECT *, ROW_NUMBER() OVER (ORDER BY rn) AS seq FROM back
)
SELECT column1, column2, column3
FROM numbered
ORDER BY seq, CASE WHEN grp = 1 THEN 0 ELSE 1 END;