用mysql创建函数
Posted
技术标签:
【中文标题】用mysql创建函数【英文标题】:Create function with mysql 【发布时间】:2018-06-23 05:23:00 【问题描述】:您好,我有一个任务: 考虑具有两个关系的员工数据库:
employee(employee-name, street, city)
works(employee-name, company-name, salary)
主键带有下划线。编写查询以查找其员工平均工资低于“第一银行公司”平均工资的公司。 酌情使用用户自定义的SQL函数(create function命令)回答上述查询,该函数以公司名称为输入,返回给定的平均工资 公司。 我创建了这个函数:
create function avg_salary (c_name varchar(30))
returns numeric(8,6)
begin
declare a_salary numeric(8,6);
select avg(salary) into a_salary
from works
where company.company_name = c_name
group by company_name;
return a_salary;
select company_name
from works
where a_salary<(select avg(salary) from works where company_name = ’ First Bank Corporation’);
end
但我收到一条错误消息:
错误 1415 (0A000) : 不允许从函数返回结果集
我不明白为什么会出现此错误。 谢谢你的帮助
【问题讨论】:
mysql 还是 t-sql ?这是 sql-server 的吗?大不同 我猜书中写的只是SQL,但我用的是MySQL命令行客户端) 好的,我试试,非常感谢 也不起作用,我得到同样的错误( 【参考方案1】:您应该结合您的教程阅读 mysql 手册以了解 mysql 细节。 错误信息很清楚(每个选择都返回一个结果集)所以选择 company_name 从工作是有错的。 Selects into 和 set = (select...) 很好。 除了错误之外,“First Bank Corporation”周围的单引号很奇怪,并且在我尝试编译该函数时出错。 也是按公司名称分组;将在我的 sql 的更高版本中被拒绝,因为 company_name 未包含在选择列表中。请参阅https://dev.mysql.com/doc/refman/8.0/en/group-by-handling.html - 在这种情况下不需要它,因为您正在为指定的公司进行平均。 Mysql还需要在create函数前后设置分隔符,函数中有多个语句见https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html
【讨论】:
【参考方案2】:试试这个(示例包括我用来创建所有对象和插入数据的所有代码):
DROP TABLE IF EXISTS employee;
CREATE TABLE IF NOT EXISTS employee (
`employee-name` varchar(100) NOT NULL,
`street` varchar(100) NOT NULL,
`city` varchar(100) NOT NULL,
PRIMARY KEY (`employee-name`)
);
DROP TABLE IF EXISTS works;
CREATE TABLE IF NOT EXISTS works (
`employee-name` varchar(100) NOT NULL,
`company-name` varchar(100) NOT NULL,
`salary` numeric(8,2) NOT NULL,
PRIMARY KEY (`employee-name`)
);
INSERT INTO
employee
(`employee-name`, `street`, `city`)
VALUES
('Employee 01', '1234 State ST.', 'Your City'),
('Employee 02', '1234 State ST.', 'Your City'),
('Employee 03', '1234 State ST.', 'Your City'),
('Employee 04', '1234 State ST.', 'Your City'),
('Employee 05', '1234 State ST.', 'Your City'),
('Employee 06', '1234 State ST.', 'Your City'),
('Employee 07', '1234 State ST.', 'Your City'),
('Employee 08', '1234 State ST.', 'Your City'),
('Employee 09', '1234 State ST.', 'Your City'),
('Employee 10', '1234 State ST.', 'Your City'),
('Employee 11', '1234 State ST.', 'Your City'),
('Employee 12', '1234 State ST.', 'Your City'),
('Employee 13', '1234 State ST.', 'Your City'),
('Employee 14', '1234 State ST.', 'Your City'),
('Employee 15', '1234 State ST.', 'Your City'),
('Employee 16', '1234 State ST.', 'Your City'),
('Employee 17', '1234 State ST.', 'Your City'),
('Employee 18', '1234 State ST.', 'Your City'),
('Employee 19', '1234 State ST.', 'Your City'),
('Employee 20', '1234 State ST.', 'Your City'),
('Employee 21', '1234 State ST.', 'Your City'),
('Employee 22', '1234 State ST.', 'Your City');
INSERT INTO
works
(`employee-name`, `company-name`, `salary`)
VALUES
('Employee 01', 'Company 01', 10000.00),
('Employee 02', 'Company 01', 10000.00),
('Employee 03', 'Company 01', 10000.00),
('Employee 04', 'Company 01', 10000.00),
('Employee 05', 'Company 01', 10000.00),
('Employee 06', 'Company 02', 15000.00),
('Employee 07', 'Company 02', 15000.00),
('Employee 08', 'Company 02', 15000.00),
('Employee 09', 'Company 03', 20000.00),
('Employee 10', 'Company 03', 20000.00),
('Employee 11', 'Company 03', 20000.00),
('Employee 12', 'Company 03', 20000.00),
('Employee 13', 'Company 03', 20000.00),
('Employee 14', 'Company 03', 20000.00),
('Employee 15', 'Company 03', 20000.00),
('Employee 16', 'Company 04', 60000.00),
('Employee 17', 'Company 04', 60000.00),
('Employee 18', 'Company 04', 60000.00),
('Employee 19', 'First Bank Corporation', 17000.00),
('Employee 20', 'First Bank Corporation', 17000.00),
('Employee 21', 'First Bank Corporation', 17000.00),
('Employee 22', 'First Bank Corporation', 17000.00);
DROP FUNCTION IF EXISTS avg_salary;
DELIMITER $$
CREATE FUNCTION IF NOT EXISTS avg_salary (c_name varchar(100))
RETURNS numeric(8,2)
BEGIN
DECLARE a_salary numeric(8,2);
SELECT avg(salary) INTO a_salary FROM works WHERE `company-name` = c_name GROUP BY `company-name`;
RETURN a_salary;
END$$
DELIMITER ;
SELECT
`company-name`
FROM
works
WHERE
avg_salary(`company-name`) < avg_salary('First Bank Corporation')
GROUP BY
`company-name`
它非常适合我,返回公司 01 和公司 02 作为结果。
在原始海报评论后添加。查询现在返回平均工资以及公司名称,
SELECT
`company-name` AS `Company Name`,
avg_salary(`company-name`) AS `AVG Salary`
FROM
works
WHERE
avg_salary(`company-name`) < avg_salary('First Bank Corporation')
GROUP BY
`company-name`
【讨论】:
非常感谢这么大的工作,它也适用于我,但它不返回给定公司的平均工资,它返回公司名称 不客气!该函数实际上完全按照您帖子中的内容执行,它将公司名称作为输入并返回每家公司的平均工资。然后查询使用该函数并返回满足平均工资低于 First Bank Corporation 标准的公司列表。如果您需要查询同时返回工资,可以这样做,但这不是您提交的作业中指定的内容,所以我不想打扰,除非您确定这确实是您需要的。跨度> 好的,我有一点时间,这很容易,所以我在原始答案中添加了一个额外的查询。第二个查询返回公司名称和平均工资。 不客气!很高兴我能帮上忙。请将我的回复标记为答案,以便人们知道问题已解决。谢谢! 我做到了。谢谢!【参考方案3】:试试下面的方法:
create function avg_salary (c_name varchar(30))
returns numeric(18,6)
begin
declare a_salary numeric(18,6);
set a_salary = select avg(salary) from works where company_name = c_name;
return (a_salary);
end
select company_name from works where a_salary<(select avg_salary('First Bank Corporation'));
【讨论】:
现在我收到一条关于 sql 语法的错误消息'= select avg(salary)...'以上是关于用mysql创建函数的主要内容,如果未能解决你的问题,请参考以下文章