查看: 501|回复: 13

围棋收官与SQL

[复制链接]
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
发表于 2024-9-9 09:20 | 显示全部楼层 |阅读模式
本帖最后由 wabjtam123 于 2024-9-13 06:07 编辑

准备和大家探讨一个有趣话题,先介绍围棋官子收束顺序的基本思路,再探讨如何与数据库SQL实现结合。
itpub我贴不了图,完整的链接见公众号
https://mp.weixin.qq.com/s/4YTmyBF-TB2mAa0sAmaFZw

论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 2024-9-9 09:20 | 显示全部楼层
本帖最后由 wabjtam123 于 2024-9-9 10:16 编辑

最近经常接触围棋,忽然有灵感,就用古代战争做比喻,粗浅写一个围棋官子和数据库结合的文章,顺便普及普及围棋,兄弟们多多指点。文中SQL的逻辑是假设这按这个收官顺序规则去抢夺城池,套规则进去的,如果是能分析出什么顺序组合**,才更有意义,大家一起讨论讨论,如果考虑大小就会很复杂,还有你我都可以不理双先的情况,考虑收益与损失比就更复杂了。

从围棋收官到秦楚大战的数据库SQL实现


前言
在这个万物互联的时代,创新常常源于跨界思维。人工智能的发展启示我们,掌握多领域知识并融多领域知识并融会贯会贯通,才能在看似无关的领域之间搭建桥梁,创造新的可能性。
今天,我们将穿越千年,探讨围棋与数据库的交融。围棋是古老智慧的结晶,数据库则是现代技术的象征。当两者相遇,会擦出怎样的火花?
通过模拟秦楚战争,我们将揭示围棋收官与攻城策略的微妙关联,并展示如何用SQL语言实现这一切。准备好了吗?一场跨越时空的智慧碰撞,即将开始。





1 秦孝公大战商鞅
公元前333年,秦孝公和商鞅下围棋,其儿子嬴驷、嬴华在一旁观战,双方大战333手,最终秦孝公败下阵来。
商鞅:大王您布局占优,只是输在了收官。主要是一处双先被我给抢了,临近终局又有一处单先您没有及时下到,又被我给逆收了,这才得以幸运小胜。
秦孝公:是啊,这两处失误着实不应该。
这些收官术语让观战的嬴驷、嬴华听的有些云里雾里,于是商鞅当即就给两位少年开启了围棋官子小课堂。
商鞅:围棋顾名思义,围地盘的棋,胜负就取决于谁的地盘围得更大。黑白双方轮番落子,不允许一方连下两手,比如我取得梦寐以求的A点,你就可以占据心心念念的B点。但是有一种特殊的情况,就是我占到A点后你却不敢去占B点,需要跟着我应一手,于是B点又落入我手。符合这种特征的A点,就是先手。
两位公子点点头,商鞅继续解释。
商鞅:不过如果一方走到A点,另一方不搭理也不会出事,可以放心地抢占他处(如B点)。此时在A点落子就被称之为后手。
嬴驷:那我们下棋是不是要判断下的是先手还是后手,优先考虑先手。
商鞅:公子聪明。先手更准确的叫单先,如A点对甲是先手,对乙却不是。
嬴华:老师,我猜到你们提到的双先啥意思,是不是无论黑白哪一方行棋,A点对他们而言都是先手,此时在A点的落子就被称之为双先。
商鞅:正确!最后还有一个逆收的概念,能猜到啥意思吗?
嬴驷:通过这个“逆”字推测,逆收会不会是A点对某一方(比如黑方)是先手,对另一方(比如白方)是后手,但是黑方没及时下A点,被白方给抢占了。
商鞅:两位公子机智过人,乃我秦之大幸啊。
两位公子:是老师引导得好。
术语   解释
单先 己方的关键点,占据后对方必须立即应对,否则将遭受明显损失。
双先 双方都认为紧急且必须立即应对的点,无论谁下都会迫使对方做出回应。
后手 对方可以不立即应对的着手
逆收 抢先占据对方的单先点,阻止对方获得先手权利。

   

2 收官类型与城池特征

商鞅:单先、后手、双先、逆收这四种收官类型你们搞明白了,这里我想问问两位,这四种收官手法的优先级如何,你们行棋中会考虑它们的顺序吗?
嬴驷和嬴华陷入沉思...
秦孝公:驷儿,华儿,围棋和战争很类似,父王和你们探讨接下来的战事规划,把这整明白了,围棋收官顺序也就水落石出了。
两位公子顿时来了精神。
秦孝公:吾儿,咱们秦国即将与楚国展开八大城池的争夺战,一旦能夺其大部分,则天下局势将对秦国极其有利,否则就不好说了。
嬴驷:父王,那胜算如何?
秦孝公:我和商君研究过,从围棋收官角度来看,我军必取大捷。
接着秦孝公领着众人来到地图前,他飞快的圈出这八座城池,然后继续探讨。
秦孝公:大家看这八座城池,分别是双先城池两座、单先城池两座,逆收城池两座,还有后手城池两座。
嬴华:父王,您太有趣了,还真将围棋收官搬到战场上来啊。
秦孝公:嗯,双先城池处平原地带,分别名为平原1和平原2,两处城池粮食充裕,无论秦楚占得此地都能得到充足的补给,可以此为依托,即刻攻占新的城池。
单先城池地处草原地带,分别名为草原1和草原2,两处城池地域辽阔草木茂盛,这对我们骑兵大军来说非常重要,不过对于楚军来说却并不适应。
逆收城池处于山水地带,分别名为山水1和山水2,这对于擅长水上作业山间种植的楚国人来说是天赐佳境,得到后可立即依托于此继续攻占新城。可惜我们秦军对这种环境并不适应,攻占下来需要适应和调整,无法即刻再攻城略地。
最后的两座后手城池地处高原地带,分别名为高原1和高原2,这两处无平原、无河流、无草原,谁占到此处都不能得到充分的补给,无法即刻奔赴新战场。
听秦孝公将战争与收官术语这么一结合,两位公子恍然大悟,理解的更为深刻了。同时他们都向父王表态,要上阵去和楚国决一死战。
看着两个儿子英勇的样子,秦孝公很是欣慰。







3 收官顺序与攻城策略

秦孝公:吾儿,现在双方兵力已经各自集结,大战一触即发。我军与楚军实力都很了得,无论哪一方只要拿下的城池能给其充分的补给,都能即刻抢占下一城池,而另一方只能避其锋芒。
嬴驷:那谁能占得先机,率先出击,就显得尤为重要了啊。
秦孝公:放心,秦国骑兵强大,速度所向无敌,先机在我们这。有感而发写了围棋和
两位公子面露喜色。
商鞅:两位公子,如果让你们带兵上阵,这八座城池准备依据什么顺序去攻打,最多能拿下几座城池。
秦孝公:哈哈,这和商君刚才提问的收官顺序,是同一个问题哦。
嬴驷:老师,我认为先攻双先城平原1,再灭平原2。随即将单先城草原1拿下,再进军草原2,最后攻占后手城高原1,不过高原1无法提供充足补给,我们只能修生养息,此时轮到楚国出手,会接连拿下山水1、山水2以及最后的高原2。如此一来,我军拿下八座城池中的五座,楚军则取其三。
嬴华:我觉得拿下平原1,平原2,草原1,草原2后接下来攻打的应该是山水1,而非高原1 。虽说山水1不是秦军理想之地,却是楚军的理想之地。夺取之后楚军仅剩山水2可选,即便有充足补给助其继续出征,剩下的也只有高原1和高原2这两个后手之城,若取高原1后修生养息,则高原2就落入我军之手。如此应该是秦军拿下八座城池中的六座,楚军仅取其二,整体过程如表格所示。
顺序 特征 城池占 方说明
1 双先 平原1秦    双先城池,秦国占领后有下一次连续抢占新城池的机会
2 双先 平原2 双先城池,秦国占领后有下一次连续抢占新城池的机会
3 秦先手 草原1   秦先手城池,秦国占领后有下一次连续抢占新城池的机会
4 秦先手 草原2秦先手城池,秦国占领后有下一次连续抢占新城池的机会
5 楚先手 山水1 楚先手城池,虽说秦国逆收抢占后该城池归秦,但是秦不能再连续抢占,接下来新城池要轮到楚抢夺了
6 楚先手山水2 楚先手城池,楚国有下一次连续抢占新城池的机会
7 后手 高原1 后手城池,楚国抢占后失去下一次连续抢占新城池的机会,接下来要轮到秦了
8 后手 高原2秦   后手城池,最后一个城池归秦所有,再无新城池,战斗结束。

嬴驷:弟弟厉害,是哥哥错了。
嬴华:哦,老师,攻城的顺序就是双先、单先、逆手、后手。这也就围棋的收官顺序了。
商鞅:很好!这下你把围棋如何收官的问题也一并回答了,来,各位看看我画的收官的单手棋流程图,理解一下。
众人看了流程图频频点头。
商鞅:我再出一道围棋题来考考两位,行棋至此,轮白下,请问如何收官?
嬴华思考片刻,心中有了答案,随即开始边摆棋边回答商鞅
嬴华:老师,白1抢完双先后立即夺取白7单先,随后走到白11逆收,最后剩下后手官子,如此终局即可半目获胜。
商鞅点头称是,秦孝公大喜过望,当即准许赢华其随征讨大将军一同出征,此次少年出战,也为将来成就秦国第一猛将打下了铺垫。
此时的嬴驷的脸上闪烁出一丝不易察觉的笑容,却正好被商鞅看在眼里,商鞅心里一颤,似乎明白了什么。而此时的秦孝公却在准备给大家一个惊喜。




4 秦孝公展示SQL神功

秦孝公:商君、驷儿,华儿,你们会说战国许多国家的语言,不过最近一个奇遇,让我学会了一门新语言,可比你们都厉害。
商鞅:哇,恭喜大王,敢问是什么语言?
秦孝公:SQL语言,这语言可不是用来说话,而是能分析预测出各种结果,比如可以告知秦楚争夺城池的结果,甚至比这更复杂的情况也能分析。
众人一脸懵逼 ...
秦孝公拿出了他在奇遇中得来的设备,一番敲打后,开始了数据库建模和SQL语言的编写过程。
建表和插入数据
-- 创建城池表
CREATE TABLE cities (
    id NUMBER(5) PRIMARY KEY,
    name VARCHAR2(50),
    type VARCHAR2(10)
);

-- 插入城池数据
INSERT INTO cities (id, name, type) VALUES (1, '平原1', '双先');
INSERT INTO cities (id, name, type) VALUES (2, '平原2', '双先');
INSERT INTO cities (id, name, type) VALUES (3, '草原1', '秦先手');
INSERT INTO cities (id, name, type) VALUES (4, '草原2', '秦先手');
INSERT INTO cities (id, name, type) VALUES (5, '山水1', '楚先手');
INSERT INTO cities (id, name, type) VALUES (6, '山水2', '楚先手');
INSERT INTO cities (id, name, type) VALUES (7, '高原1', '后手');
INSERT INTO cities (id, name, type) VALUES (8, '高原2', '后手');
编写SQL如下

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,
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
    FROM cities c , type_counts tc

where  c.type = tc.type
)
SELECT
    captured_by AS category,
    COUNT(*) AS count,
    LISTAGG(name, ', ') WITHIN GROUP (ORDER BY id) AS cities
FROM capture_process
GROUP BY captured_by
;

关键点说明:
  a. 双先和秦先手:直接归秦国所有。
  b. 楚先手
     使用 ROW_NUMBER() 函数为每个楚先手城池分配一个序号。
     只有第一个(序号为1)的楚先手城池被秦国逆收,其余全部归楚国。
     这确保了无论有多少个楚先手城池,秦国只能逆收一个。
  c. 后手
     同样使用 ROW_NUMBER() 函数分配序号。
     使用 FLOOR(tc.type_count / 2) 判断各自应该占领的城池数量。
执行这个查询,结果是:      

category          COUNT              cities
楚                     2                     山水2, 高原1
秦                     6                    平原1, 平原2, 草原1, 草原2, 山水1, 高原2

显示秦占领6座城池,而楚仅占领了2座,验证了嬴华的分析思路是正确的。
众人震惊不已,连呼:SQL语言好厉害,此乃天助大秦一统天下也!
......本集完




1. 古代围棋规则和现代略有不同,为方便大家理解,本文以现代围棋规则为准;
2. 围棋的收官是很复杂的,双先、单先、逆手、后手的顺序只能确保大致正确,实际收官时要根据棋盘的具体情况具体分析,主要和每手棋的目数有关,后手足够大时,**考虑后手都有可能;
3. 对应的抢夺城池的情况也是如此,不能仅以城池个数做依据,实际战斗中需要结合城池的大小考虑才更合理,这也就是前面说的围棋收官需要结合每一手棋的目数综合考虑类似;
4. 本文是基于极简围棋收官下的建模与实现,后续会考虑讲述更为复杂的收官,比如什么情况下逆收比后手大,双先就一定要应吗?你抢一个双先,我也抢一个,我不理有损失,那你不理就没损失吗,如何判断?这些有待下回分解。


















使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2024-9-9 09:40 | 显示全部楼层
谢科刚输给了一力辽

使用道具 举报

回复
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 2024-9-9 10:42 | 显示全部楼层
〇〇 发表于 2024-9-9 09:40
谢科刚输给了一力辽

 好事,我就希望一力辽赢啊,日本20年没拿世界冠军了。

使用道具 举报

回复
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 2024-9-9 12:34 | 显示全部楼层
〇〇 发表于 2024-9-9 09:40
谢科刚输给了一力辽

日本20年没拿世界**了,这次夺冠是好事啊

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2024-9-9 21:44 | 显示全部楼层
故事很有趣,可是看不懂秦国为什么能顺利拿下两个双先?楚国不会也抢一个吗?

使用道具 举报

回复
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 2024-9-13 06:04 | 显示全部楼层
本帖最后由 wabjtam123 于 2024-9-13 06:14 编辑
newkid 发表于 2024-9-9 21:44
故事很有趣,可是看不懂秦国为什么能顺利拿下两个双先?楚国不会也抢一个吗?

newkid兄非常敏锐,实际下棋中如果双先全部被人抢走,基本就是要输棋了。单先或者双先就是对方如果不理会,就会遭遇损失。不过如果自己也抢双先,理论上对方也会有损失的,所以这时候就应该豁出去 ,和对方拼了,你让我有损失,我也让你有损失。关于损失的多少,这块可以量化的,未来续集我就想说这个。
先手无非就是对方不理会让对方产生损失,但是反过来也是如此啊,就要拼一把,不能无端的退让。如果我们反击让对手害怕而搭理了我们,那就双方扯皮了,我们就不吃亏了。

使用道具 举报

回复
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 2024-9-13 06:08 | 显示全部楼层
本帖最后由 wabjtam123 于 2024-9-13 06:29 编辑
flyingsql 发表于 2024-9-12 08:41
文章很有新意,内容很好,楼主您的文章我可以转载吗?众人震惊不已,连呼:SQL语言好厉害,此乃天助大秦一 ...

没问题,可以转。ITPUB没有完整的图片,因为我贴不上去。完整的见我的公众号文章https://mp.weixin.qq.com/s/4YTmyBF-TB2mAa0sAmaFZw
我可以开公众号白名单给你,欢迎关注并多多指点。

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2024-9-13 21:51 | 显示全部楼层
wabjtam123 发表于 2024-9-13 06:08
没问题,可以转。ITPUB没有完整的图片,因为我贴不上去。完整的见我的公众号文章https://mp.weixin.qq.com/ ...

微信比较小气,不让人引用图片,你必须先把图片存在本地,然后在发帖的时候上传。

使用道具 举报

回复
论坛徽章:
50
2014年世界杯参赛球队: 荷兰
日期:2014-07-11 07:56:59蛋疼蛋
日期:2012-03-06 07:22:542012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-02-13 15:09:522012新春纪念徽章
日期:2012-01-04 11:53:29蛋疼蛋
日期:2011-11-11 15:47:00ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
 楼主| 发表于 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;

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表