我在尝试从数字表中进行SELECT时会收到此错误(“结果由多行组成”)并附加一个包含前4条记录总和的列(即添加两列中的值)该记录以及来自接下来3个记录的列)。总计列使用FUNCTION生成。这是我的简化示例 - 首先创建并填充表格:
CREATE TABLE test.table1 (
num1 float DEFAULT NULL,
num2 float DEFAULT NULL
);
INSERT INTO test.table1
(num1, num2)
VALUES
(2.5, 3.2),
(1.4, 0.9),
(1.7, 2.3),
(2.6, 1.2);
(3.3, 0.8);
(2.0, 2.2);
现在,创建FUNCTION:
DROP FUNCTION IF EXISTS ADDNUM;
DELIMITER $$
CREATE FUNCTION ADDNUM (num1 float, num2 float) RETURNS float
DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE total, sum1 float;
DECLARE maxv int UNSIGNED DEFAULT 4;
DECLARE i int UNSIGNED DEFAULT 0;
WHILE i < maxv DO
SELECT (num1 + num2) INTO sum1 FROM table1;
SET total = total + sum1;
SET i = i + 1;
END WHILE;
RETURN (total);
END
$$
当我在SELECT语句中调用该函数时,我收到了上述错误。
SELECT num1, num2, addnum(t.num1, t.num2) AS 'Sum' FROM table1 t;
任何想法如何解决这个问题?或者也许有一种更简单的方法来实现我的最终结果。我对MySQL非常陌生,所以可能从错误的角度来看待它。
提前致谢!
答案 0 :(得分:1)
好的,我以不同的方式解决了这个问题,最终达到了预期的效果。如果有人遇到同样的问题,这就是代码。我解决的方法是使用“动态”视图而不是循环。我不确定这是否是最优雅的做事方式,但我还在学习,它对我有用,所以嘿!
1)首先要创建表
CREATE TABLE table2 (
DateT date DEFAULT NULL,
HTeam varchar(255) DEFAULT NULL,
ATeam varchar(255) DEFAULT NULL,
HScore int(10) UNSIGNED DEFAULT NULL,
AScore int(10) UNSIGNED DEFAULT NULL
) ENGINE = INNODB;
2)填充数据
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-01', 'T1', 'T2', 1, 0);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-01', 'T3', 'T4', 2, 1);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-08', 'T2', 'T3', 2, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-08', 'T4', 'T1', 0, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-15', 'T1', 'T3', 3, 1);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-15', 'T2', 'T4', 1, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-22', 'T4', 'T2', 3, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-22', 'T3', 'T1', 0, 0);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-29', 'T1', 'T4', 1, 1);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-03-29', 'T3', 'T2', 4, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-04-05', 'T2', 'T1', 0, 2);
INSERT INTO test.table2(DateT, HTeam, ATeam, HScore, AScore) VALUES
('2014-04-05', 'T4', 'T3', 3, 1);
3)接下来,我创建了一些函数,我稍后可以在视图中使用这些函数使它们以“动态”方式运行。这是我在这个网站上遇到的一个小技巧:
DROP FUNCTION IF EXISTS func_hteam;
CREATE FUNCTION func_hteam() RETURNS VARCHAR(255) DETERMINISTIC
RETURN @hteam;
DROP FUNCTION IF EXISTS func_ateam;
CREATE FUNCTION func_ateam() RETURNS VARCHAR(255) DETERMINISTIC
RETURN @ateam;
DROP FUNCTION IF EXISTS func_datet;
CREATE FUNCTION func_datet() RETURNS date DETERMINISTIC
RETURN @datet;
4)接下来,我创建了一个“动态”视图:
DROP VIEW IF EXISTS view_total;
CREATE VIEW view_total (DateT, HTeam, ATeam, HScore, AScore, Total)
AS
(SELECT DateT, HTeam, ATeam, HScore, AScore, (HScore + AScore) AS 'Sum' FROM test.table2
WHERE (HTeam = func_hteam() OR ATeam = func_hteam()) AND DateT < func_datet()
ORDER BY DateT DESC LIMIT 4)
UNION DISTINCT
(SELECT DateT, HTeam, ATeam, HScore, AScore, (HScore + AScore) AS 'Sum' FROM test.table2
WHERE (HTeam = func_ateam() OR ATeam = func_ateam()) AND DateT < func_datet()
ORDER BY DateT DESC LIMIT 4)
ORDER BY DateT DESC;
5)接下来,我创建了一个函数来计算上一个视图返回的所有行的总和:
DROP FUNCTION IF EXISTS func_total;
DELIMITER $$
CREATE FUNCTION func_total() RETURNS int DETERMINISTIC
BEGIN
DECLARE num int UNSIGNED DEFAULT 0;
SELECT SUM(total) INTO num FROM view_total;
RETURN (num);
END
$$
6)最后,将所有这些凝胶组合在一起的功能:
DROP FUNCTION IF EXISTS func_final;
DELIMITER $$
CREATE FUNCTION func_final(hteam VARCHAR(255), ateam VARCHAR(255), datet DATE) RETURNS int DETERMINISTIC
BEGIN
DECLARE total INT DEFAULT 0;
SELECT func_total() INTO total
FROM (SELECT @hteam:=hteam hteam,
@ateam:=ateam ateam,
@datet:=datet datet) t1, view_total t
ORDER BY t.datet ASC LIMIT 1;
RETURN (total);
END
$$
7)...现在我们得到了数据:
SELECT DateT, HTeam, ATeam, HScore, AScore, func_final(HTeam, ATeam, Datet) AS TOTAL
FROM table2 ORDER BY DateT DESC;
所有的作品,这可以用更好的方式写出来吗?也许,但现阶段超出了我的能力:)
美好的一天! :P
答案 1 :(得分:0)
错误来自
SELECT (num1 + num2) INTO sum1 FROM table1
它尝试从table1
选择多个行到一个变量sum1
。要解决此问题,您可以使用
limit
结果集
SELECT (num1 + num2) INTO sum1 FROM table1 limit 1
此外,您必须初始化变量total
declare total float default 0;
否则,其值将为NULL,请参阅DECLARE
使用变量limit
或offset
的解决方案似乎是prepare
和execute
声明
prepare stmt from "select * from table1 limit ? offset ?";
execute stmt using lim, off;
有关更详细和详细的解决方案,另请参阅Variable LIMIT Clause in MySQL或Using variables as OFFSET in SELECT statments inside mysql's stored functions。
还有SP does not accept variables in LIMIT clause的错误报告/功能请求以及版本5.5.6和6.0.14中的修复http://bugs.mysql.com/bug.php?id=11918#c328636的提示。