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配置中


    今天遇到个很迷的问题,先上代码:

    1. <?php
    2. //获取用户设备最新登录结果集
    3. $loginLogQuery = (new Query())
    4. ->select(['user_id', 'device_id', 'created_at'])
    5. ->from(LoginLog::tableName())
    6. ->groupBy(['user_id', 'device_id']) //注意这个groupBy中的字段,必须得与上面select的字段保持一致,否则可能会出现由sql_mode引起的group by问题
    7. ->orderBy(['created_at' => SORT_DESC]);
    8. $result = array();
    9. // 创建查询器
    10. $query = new Query();
    11. $query->select([
    12. 'uad.nick',
    13. 'u.user_name',
    14. 'ude.user_device_name',
    15. 'ude.id',
    16. 'ude.user_id',
    17. 'ude.user_device_type',
    18. 'ude.created_at AS dcat',
    19. 'ude.user_device_info',
    20. 'q.created_at AS login_at'
    21. ])
    22. ->from(['ude' => UserDevices::tableName()])
    23. ->leftJoin(['u' => User::tableName()], 'ude.user_id = u.id')
    24. ->leftJoin(['uad' => UserAdditionals::tableName()], 'u.id = uad.user_id')
    25. ->leftJoin(['q' => $loginLogQuery], 'q.user_id=ude.user_id AND q.device_id=ude.id')
    26. ->where(['u.domain_id' => $params['domain_id']]);
    27. if (!empty($params['type'])) {
    28. $query->andWhere('ude.user_device_type = :type', [':type' => $params['type']]);
    29. }
    30. $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]);