错误“结果由多行组成”

时间:2014-06-22 21:52:26

标签: mysql sql

我在尝试从数字表中进行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非常陌生,所以可能从错误的角度来看待它。

提前致谢!

2 个答案:

答案 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


使用变量limitoffset的解决方案似乎是prepareexecute声明

prepare stmt from "select * from table1 limit ? offset ?";
execute stmt using lim, off;

有关更详细和详细的解决方案,另请参阅Variable LIMIT Clause in MySQLUsing 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的提示。