|
楼主 |
发表于 2024-9-14 08:42
|
显示全部楼层
接下来要考虑大小的问题了,简单的规则就是双先,单先,逆收,后手这个顺序不变,或者对应攻城的(双先城,秦先手城,楚先手城,后手城),但是城池的大小是有区别的,要在原来的顺序的基础上从大收到小,这样略微复杂一些。围棋就是这么下的。增加城池尺寸的字段,然后参与排序一下。-- 创建城池表
CREATE TABLE cities (
id NUMBER(5) PRIMARY KEY,
name VARCHAR2(50),
type VARCHAR2(10),
size NUMBER(5)
);
-- 插入城池数据,包括大小
INSERT INTO cities (id, name, type, size) VALUES (1, '平原1', '双先', 80);
INSERT INTO cities (id, name, type, size) VALUES (2, '平原2', '双先', 75);
INSERT INTO cities (id, name, type, size) VALUES (3, '草原1', '秦先手', 70);
INSERT INTO cities (id, name, type, size) VALUES (4, '草原2', '秦先手', 65);
INSERT INTO cities (id, name, type, size) VALUES (5, '山水1', '楚先手', 85);
INSERT INTO cities (id, name, type, size) VALUES (6, '山水2', '楚先手', 60);
INSERT INTO cities (id, name, type, size) VALUES (7, '高原1', '后手', 90);
INSERT INTO cities (id, name, type, size) VALUES (8, '高原2', '后手', 55);
WITH type_counts AS (
SELECT type, COUNT(*) AS type_count
FROM cities
GROUP BY type
),
capture_process AS (
SELECT
c.id, c.name, c.type, c.size,
CASE
WHEN c.type = '双先' THEN '秦'
WHEN c.type = '秦先手' THEN '秦'
WHEN c.type = '楚先手' THEN
CASE
WHEN ROW_NUMBER() OVER (PARTITION BY c.type ORDER BY c.id) = 1 THEN '秦'
ELSE '楚'
END
WHEN c.type = '后手' THEN
CASE
WHEN ROW_NUMBER() OVER (PARTITION BY c.type ORDER BY c.id) <= FLOOR(tc.type_count / 2) THEN '楚'
ELSE '秦'
END
END AS captured_by,
CASE
WHEN c.type = '双先' THEN 1
WHEN c.type = '秦先手' THEN 2
WHEN c.type = '楚先手' THEN 3
WHEN c.type = '后手' THEN 4
END AS type_order
FROM cities c , type_counts tc
WHERE c.type = tc.type
)
SELECT
captured_by AS category,
COUNT(*) AS count,
LISTAGG(name || ' (' || type || ', 大小: ' || size || ')', ', ')
WITHIN GROUP (ORDER BY
type_order,
CASE WHEN type = '楚先手' AND captured_by = '秦' THEN 0 ELSE 1 END,
CASE WHEN type = '后手' AND captured_by = '秦' THEN 1 ELSE 0 END,
id
) AS cities
FROM capture_process
GROUP BY captured_by
ORDER BY
CASE WHEN captured_by = '秦' THEN 1 ELSE 2 END,
COUNT(*) DESC;
|
|