非常有意思的一个sql题目,两种思路展现了两种对sql的理解:
有如下表:
center | receive_date | material | orgland
--------+--------------+----------+----------
东京 | 2007-04-01 | 锡 | 智利
东京 | 2007-04-12 | 锌 | 泰国
东京 | 2007-05-17 | 铝 | 巴西
东京 | 2007-05-20 | 锌 | 泰国
大阪 | 2007-04-20 | 铜 | 澳大利亚
大阪 | 2007-04-22 | 镍 | 南非
大阪 | 2007-04-29 | 铅 | 印度
名古屋 | 2007-03-15 | 钛 | 玻利维亚
名古屋 | 2007-04-01 | 钢 | 智利
名古屋 | 2007-04-24 | 钢 | 阿根廷
名古屋 | 2007-05-02 | 镁 | 智利
名古屋 | 2007-05-10 | 钛 | 泰国
福冈 | 2007-05-10 | 锌 | 美国
福冈 | 2007-05-28 | 锡 | 俄罗斯
(14 rows)
求出materal 和 orgland都重复的center,此答案为东京,锌-泰国组合出现了两次。
SQL语句有两种写法:
1.官方写法:
--正确答案:
SELECT
center
FROM
Materials2
GROUP BY
center
HAVING
--通过连接符号产生组合,看组合是否唯一。
COUNT(material || orgland) <> COUNT(DISTINCT material || orgland);
将material和orgland组成一个单独的词,判断不排除重复和排除重复的字段合计值是否一致,非常开脑洞的做法。
我的做法:
SELECT
DISTINCT center
FROM
Materials2 AS m1
WHERE
EXISTS(
SELECT
*
FROM
Materials2 AS m2
WHERE
m1.center = m2.center
AND m1.receive_date <> m2.receive_date
AND m1.material = m2.material
AND m1.orgland = m2.orgland
);
纯粹的列举条件组合进行筛选,对比上一个解法,就显得比较没有灵性。
对于一个要求的sql方案可能有很多种,在没有深入思考的时候,机械的写可以得到答案,但如果仔细思考,也许还有更好的解决方法。
不要限制自己的想象。
参考文献:《SQL进阶教程》作者:[日]MICK 译者:吴炎昌 人民邮电出版社 出版时间:2017-11 / 1-10 HAVING子句又回来了