我刚刚将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设置,但我不想这样做。
答案 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_name
,table1
,table2
部分才能获得使用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;