达梦数据库中的GROUP BY语句

博客分享了一次在达梦DCA证书考试中遇到的问题,即在统计各部门工资总和并筛选超过80000的部门时,由于GROUP BY语句不完整导致的错误。博主详细解释了错误原因,并提供了正确的SQL语句,强调了GROUP BY子句需包含SELECT中所有非聚合字段。同时,博主还介绍了SQL语句的基本书写顺序规则。

达梦DCA证书考试有一道题目是:统计各部门工资总和,并列出大于80000的所有部门、ID和总工资数,当时手里少写了一个条件,练习的时候想起来了,记录一下大致如下:

我写的语句:

select
        a.DEPARTMENT_ID as 部门编号,
        sum(SALARY)     as 部门工资,
        DEPARTMENT_NAME as 部门名称
from
        TEST.EMPLOYEE a,TEST.DEPARTMENT b
where   a.DEPARTMENT_ID = b.DEPARTMENT_ID
group by
        a.DEPARTMENT_ID
having  sum(SALARY) > 80000
ORDER BY
        a.DEPARTMENT_ID;

报错:

错误[-4080]:

不是 GROUP BY 表达式

问题原因:

ORACLE或者DMDB库中:GROUP BY后面必须加上你SELECT后面所查询的所有除聚合函数之外的所有字段,原语句太粗心少写了一个列。

正确语句:

select
        a.DEPARTMENT_ID as 部门编号,
        sum(SALARY)     as 部门工资,
        DEPARTMENT_NAME as 部门名称
from
        TEST.EMPLOYEE a,TEST.DEPARTMENT b
where   a.DEPARTMENT_ID = b.DEPARTMENT_ID
group by
        a.DEPARTMENT_ID,DEPARTMENT_NAME
having  sum(SALARY) > 80000
ORDER BY
        a.DEPARTMENT_ID;

语句等价于:

select
        a.DEPARTMENT_ID as 部门编号,
        sum(SALARY)     as 部门工资,
        DEPARTMENT_NAME as 部门名称
from
        TEST.EMPLOYEE a
inner join TEST.DEPARTMENT b
on
        a.DEPARTMENT_ID = b.DEPARTMENT_ID
group by
        a.DEPARTMENT_ID,
        DEPARTMENT_NAME
having
        sum(SALARY) > 80000
ORDER BY
        a.DEPARTMENT_ID;

补充SQL基本关键词书写顺序规则:

select==》from==》where==》group by==》having==》order by

达梦数据库(DM8)中使用 `GROUP BY` 语句时,如果遇到“不是 GROUP BY 表达式”的报错,通常是因为查询字段未完全包含在 `GROUP BY` 子句中。以下是几种解决方法: 1. **将所有查询字段添加到 `GROUP BY` 子句中** 达梦数据库在分组查询时,要求 `SELECT` 中出现的所有字段都必须包含在 `GROUP BY` 子句中。例如,以下 SQL 语句: ```sql SELECT R.ID, R.ROLE_NAME, R.APP_CODE, R.APP_NAME FROM ROLES R GROUP BY R.APP_CODE, R.APP_NAME; ``` 会因为 `R.ID` 和 `R.ROLE_NAME` 未出现在 `GROUP BY` 子句中而报错。正确的写法是: ```sql SELECT R.ID, R.ROLE_NAME, R.APP_CODE, R.APP_NAME FROM ROLES R GROUP BY R.ID, R.ROLE_NAME, R.APP_CODE, R.APP_NAME; ``` 这样可以确保所有查询字段都参与分组,避免报错[^1]。 2. **使用 `GROUP_OPT_FLAG` 提示参数** 达梦数据库支持通过在查询中添加 `GROUP_OPT_FLAG(1)` 提示来放宽对 `GROUP BY` 的限制。例如: ```sql SELECT /*+ GROUP_OPT_FLAG(1)*/ ID, NAME FROM "TEST"."TEST" GROUP BY "NAME"; ``` 该方法允许在 `SELECT` 中包含未在 `GROUP BY` 子句中列出的字段,从而避免报错[^2]。 3. **使用 `COMPATIBLE_MODE` 参数兼容其他数据库模式** 如果希望 `GROUP BY` 行为更接近其他数据库(如 MySQL 或 Oracle),可以通过设置 `COMPATIBLE_MODE` 参数来调整达梦数据库的兼容模式。例如,将数据库设置为兼容 MySQL 模式: ```sql SP_SET_PARA_VALUE(2, 'COMPATIBLE_MODE', 4); ``` 设置完成后需要重启数据库服务以使更改生效。重启命令如下: - **Windows 系统**: ```bash net stop DmServiceDMSERVER net stop DmAPService net start DmServiceDMSERVER net start DmAPService ``` - **Linux 系统**: ```bash service DmServiceDMSERVER restart ``` 重启后,`GROUP BY` 的行为将更接近 MySQL 或 Oracle,从而减少报错的可能性[^4]。 4. **使用通配符时的处理** 如果在查询中使用了通配符(如 `*`),可能会因为达梦数据库对 `GROUP BY` 的严格要求而报错。此时可以尝试在查询中添加如下提示: ```sql SELECT /*+ GROUP_OPT_FLAG(1)*/ * FROM TABLE_NAME GROUP BY COLUMN_NAME; ``` 这样可以在一定程度上绕过对 `GROUP BY` 字段的严格检查,避免报错[^3]。 ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值