MySQL ONLY_FULL_GROUP_BY错误如果你想选择很多列或你想做SELECT *怎么办?

时间:2018-02-03 20:14:59

标签: mysql sql mysqli group-by

我刚刚将Ubuntu升级到将MySQL升级到最新版本的最新版本。我的一些查询如下面的查询失败,并出现以下预期错误:

  

查询:

SELECT ANY_VALUE(date) as thedate, ANY_VALUE(name), ordersetid, price  FROM orders LEFT OUTER JOIN addresses ON orders.addressid = addresses.id WHERE orders.owner =  'admin' GROUP BY ordersetid order by thedate DESC
  

错误:

#1055 - Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'mydb.orders.price' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

我理解解决这个问题的方法是在字段上使用聚合函数或ANY_VALUE关键字来选择如下

  

工作查询:

SELECT ANY_VALUE(date) as thedate, ANY_VALUE(name), ordersetid, ANY_VALUE(price)  FROM orders LEFT OUTER JOIN addresses ON orders.addressid = addresses.id WHERE orders.owner =  'admin' GROUP BY ordersetid order by thedate DESC

我的问题是,如果我有很多列,或者我想选择所有列,该怎么办?还有另一种方法吗?

注意:我了解如何禁用MySQL中的full_groupby_by设置,但我不想这样做。

2 个答案:

答案 0 :(得分:2)

如果你有很多专栏,那么下面的想法是什么:

第一步:您创建一个存储过程,可以执行从输入查询字符串生成的预准备语句。

第二步:您创建另一个生成所需查询字符串的存储过程。这是基于StartPrice2查询您需要从所需数据库和表中放入information_schema语句的列,并调用先前的存储过程以执行它并获得所需结果。如果您根据需要更改了它并由ANY_VALUE()调用它,那么您应该看到动态生成的查询(请参阅CALL construct_query()语句)。如果一切正常,您可以取消注释SELECT query以运行此构造的查询并获得所需的结果。

第一步:

CALL exec_stmt(query)

第二步:注意:您需要替换DROP PROCEDURE IF EXISTS exec_stmt; DELIMITER @@ CREATE PROCEDURE exec_stmt( IN stmt_str TEXT ) proc: BEGIN SET @_stmt_str = stmt_str; PREPARE stmt FROM @_stmt_str; EXECUTE stmt; DEALLOCATE PREPARE stmt; END proc @@ DELIMITER ; your_db_nametable1table2部分才能获得使用table3函数动态创建所需的列名称。

ANY_VALUE()

然后你可以调用它:

DROP PROCEDURE IF EXISTS construct_query;
DELIMITER @@
CREATE PROCEDURE construct_query()
proc: BEGIN

    DECLARE query TEXT DEFAULT NULL;
    DECLARE columns TEXT DEFAULT NULL;

    SELECT GROUP_CONCAT(CONCAT('ANY_VALUE(', COLUMN_NAME, ')'))
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_SCHEMA = 'your_db_name' AND TABLE_NAME IN ('table1', 'table2', 'table3')
    ORDER BY TABLE_SCHEMA, ORDINAL_POSITION INTO columns;

    SET query = CONCAT (
        'SELECT ',
        columns,
        ' FROM orders ',
        'LEFT OUTER JOIN addresses ON orders.addressid = addresses.id WHERE orders.owner = \'admin\' GROUP BY ordersetid ORDER BY thedate DESC'
    );

    SELECT query;
    -- CALL exec_stmt(query);

END proc @@
DELIMITER ;

答案 1 :(得分:0)

包含聚合函数真的很难吗?

SELECT ordersetid, MIN(date) as thedate, MIN(name), SUM(price)
FROM orders o LEFT OUTER JOIN
     addresses a
     ON o.addressid = a.id
WHERE o.owner =  'admin'
GROUP BY ordersetid
ORDER BY thedate DESC;