sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
放到my.ini 的mysqld配置中
今天遇到个很迷的问题,先上代码:
<?php
//获取用户设备最新登录结果集
$loginLogQuery = (new Query())
->select(['user_id', 'device_id', 'created_at'])
->from(LoginLog::tableName())
->groupBy(['user_id', 'device_id']) //注意这个groupBy中的字段,必须得与上面select的字段保持一致,否则可能会出现由sql_mode引起的group by问题
->orderBy(['created_at' => SORT_DESC]);
$result = array();
// 创建查询器
$query = new Query();
$query->select([
'uad.nick',
'u.user_name',
'ude.user_device_name',
'ude.id',
'ude.user_id',
'ude.user_device_type',
'ude.created_at AS dcat',
'ude.user_device_info',
'q.created_at AS login_at'
])
->from(['ude' => UserDevices::tableName()])
->leftJoin(['u' => User::tableName()], 'ude.user_id = u.id')
->leftJoin(['uad' => UserAdditionals::tableName()], 'u.id = uad.user_id')
->leftJoin(['q' => $loginLogQuery], 'q.user_id=ude.user_id AND q.device_id=ude.id')
->where(['u.domain_id' => $params['domain_id']]);
if (!empty($params['type'])) {
$query->andWhere('ude.user_device_type = :type', [':type' => $params['type']]);
}
$result['count'] = $query->count();
然后运行时报错:
Exception (Database Exception) ‘yii\db\Exception’ with message ‘SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘smy_20190731.simiyun_login_log.created_at’ which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
The SQL being executed was: SELECT COUNT(*) AS count FROM (SELECT uad
.nick
, u
.user_name
, ude
.user_device_name
, ude
.id
, ude
.user_id
, ude
.user_device_type
, ude
.created_at
AS dcat
, ude
.user_device_info
, q
.created_at
AS login_at
FROM simiyun_user_devices
ude
LEFT JOIN simiyun_users
u
ON ude.user_id = u.id LEFT JOIN simiyun_user_additionals
uad
ON u.id = uad.user_id LEFT JOIN (SELECT user_id
, device_id
, created_at
FROM simiyun_login_log
GROUP BY user_id
, device_id
ORDER BY created_at
DESC) q
ON q.user_id=ude.user_id AND q.device_id=ude.id WHERE u
.domain_id
=1) s
‘
网上查询得知是由于数据库设置引起sql-mode里的ONLY_FULL_GROUP_BY字段导致不能直接查询group_by包裹的之外的字段 解决mysql的配置ONLY_FULL_GROUP_BY引起的错误
但做项目改配置的话也不太合适。
不过最后通过 https://www.imooc.com/qadetail/249114?t=408465 里面的回答得到了灵感。两种解决方法:
1,select和groupby字段保持一致。但这个和想达到的有点远
<?php
$loginLogQuery = (new Query())
->select(['user_id', 'device_id', 'created_at'])
->from(LoginLog::tableName())
->groupBy(['user_id', 'device_id', 'created_at'])//注意这个groupBy中的字段,必须得与上面select的字段保持一致,否则可能会出现由sql_mode引起的group by问题
->orderBy(['created_at' => SORT_DESC]);
2,不在groupby中的字段保持唯一就行
<?php
$loginLogQuery = (new Query())
->select(['user_id', 'device_id', 'MAX(created_at) AS created_at'])
->from(LoginLog::tableName())
->groupBy(['user_id', 'device_id', 'created_at'])//注意这个groupBy中的字段,必须得与上面select的字段保持一致,否则可能会出现由sql_mode引起的group by问题
->orderBy(['created_at' => SORT_DESC]);