
最近,遇到了SQL查询适配不同数据库类型的情况,看了前人写的MySQL查询代码,再想想要怎么写Oracle的,一开始愣住了。。。


现在的需求是,看看食物分类及下属的食物数据。
我们先来看看前人写的MySQL代码:
SELECT
fc.*,
GROUP_CONCAT( f.`name` ) AS food_names
FROM
FOOD_CATEGORY fc
LEFT JOIN FOOD f ON fc.CODE = f.CAT_CODE
GROUP BY
fc.id;值得注意的是,SQL-92标准是不支持这种写法的。GROUP BY 只是fc.id,而SELECT的是fc.*。尽管SQL:1999和它之后的标准加入了非聚合列查询的可行性,就是其他非聚合(不在GROUP BY 后面列出的)的列在语义及功能上依赖聚合列(能够基于聚合列完全分组),则可以在SELECT中查询非聚合列。尽管标准允许了,但是MySQL也是默认不支持这种写法的。我们需要修改sql_mode配置才能支持这种写法。
如何修改sql_mode配置?那就是要将ONLY_FULL_GROUP_BY从sql_mode的字符串值中移除。
那如何在ORACLE上实现相同功能查询呢???ORACLE中可没有GROUP_CONCAT函数来帮助我们将join再group by后的多行数据合并成一行。
那Oracle有没有别的类似功能的函数呢?作为关系数据库大哥般存在的Oracle,不可以没有!!这就是LISTAGG
函数。
那有了LISTAGG后,就结束了吗?如果仅仅将上面MySQL写法中的GROUP_CONCAT替换成Oracle LISTAGG的写法,Oracle表示不认识你

哼!!!我Oracle也是有脾气的喔,我也不支持SELECT 非聚合列的写法。。

我淦,你牛逼行了吧,我改。。。
可是该咋改呢,

一番思前码后,嘿嘿,直接来不行,那我间接来。。。没办法,睡觉我在行,用脑不在线
铛铛铛。。。
SELECT fc.*, TMP.food_names
FROM
(SELECT fc.id, LISTAGG(f.NAME, ',') WITHIN GROUP (ORDER BY f.code) AS food_names
FROM FOOD_CATEGORY fc LEFT JOIN FOOD f ON fc.CODE = f.CAT_CODE
GROUP BY fc.id) TMP
INNER JOIN FOOD_CATEGORY fc
ON fc.id = TMP.id;
ON fd.id = TMP.id;原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。