我正在玩SQL,所以如果我在求职面试中被问到,我并不是完全无知。我的朋友最近在接受采访时被问到以下问题而且他无法得到它,我问工作中哪些人体面地了解SQL并且他不知道。你能为我解答这个问题,然后解释它是如何工作的吗?请?
* 问题 *
数据库规范化(或缺乏规范化)通常会给开发人员带来挑战。
考虑一个包含三个字段的员工数据库表:
EmployeeID
EmployeeName
EmailAddresses
每位员工(由唯一的EmployeeID标识)可能在EmailAddresses字段中包含一个或多个以逗号分隔的@ rockauto.com电子邮件地址。
数据库表定义如下:
CREATE TABLE Employees
(
EmployeeID int UNSIGNED NOT NULL PRIMARY KEY,
EmployeeName varchar(50) NOT NULL,
EmailAddresses varchar(40) NOT NULL ,
PRIMARY KEY(EmployeeID)
);
出于测试目的,这里有一些示例数据:
INSERT INTO Employees (EmployeeID, EmployeeName, EmailAddresses) VALUES
('1', 'Bill', 'bill@companyx.com'),
('2', 'Fred', 'fred@companyx.com,freddie@companyx.com'),
('3', 'Fred', 'fredsmith@companyx.com'),
('4', 'Joe', 'joe@companyx.com,joe_smith@companyx.com');
您的任务是编写一个MySQL SELECT查询,该查询将显示以上示例数据的以下输出:
Employee EmailAddress
Bill bill@companyx.com
Fred (2) fred@companyx.com
Fred (2) freddie@companyx.com
Fred (3) fredsmith@companyx.com
Joe joe@companyx.com
Joe joe_smith@companyx.com
请注意,因为有多个人姓名相同(在本例中为“Fred”),所以EmployeeID包含在括号中。
您的查询需要使用MySQL版本5.1.41兼容语法编写。您应该假设使用标准数据库升序排序完成排序:“ORDER BY EmployeeID ASC”
对于此问题,您需要提交单个SQL SELECT查询。您的查询应该能够在合理的时间内处理1000条记录的表。
答案 0 :(得分:1)
只有当您的电子邮件少于10000封时......可以接受吗?
select
if(t1.c > 1, concat(e.employeename, ' (', e.employeeid, ')'), e.employeename) as Employee,
replace(substring(substring_index(e.EmailAddresses, ',', n.row), length(substring_index(e.EmailAddresses, ',', n.row - 1)) + 1), ',', '') EmailAddress
from
(select employeename, count(*) as c from Employees group by employeename) as t1,
(select EmployeeID, length(EmailAddresses) - length(replace(EmailAddresses,',','')) + 1 as emails from Employees) as t2,
(SELECT @row := @row + 1 as row FROM
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) x,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) x2,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) x3,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) x4,
(SELECT @row:=0) as ff) as n,
Employees e
where
e.employeename = t1.employeename and
e.employeeid = t2.employeeid and
n.row <= t2.emails
order by e.employeeid;
修改强>
产生的无用数字越来越少:
select
if(t1.c > 1, concat(e.EmployeeName, ' (', e.EmployeeID, ')'), e.EmployeeName) as Employee,
replace(substring(substring_index(e.EmailAddresses, ',', n.row), length(substring_index(e.EmailAddresses, ',', n.row - 1)) + 1), ',', '') as EmailAddress
from
(select EmployeeName, count(*) as c from Employees group by EmployeeName) as t1,
(select EmployeeID, length(EmailAddresses) - length(replace(EmailAddresses,',','')) + 1 as emails from Employees) as t2,
(select `1` as row from (select 1 union all select 2 union all select 3 union all select 4) x) as n,
Employees e
where
e.EmployeeName = t1.EmployeeName and
e.EmployeeID = t2.EmployeeID and
n.row <= t2.emails
order by e.EmployeeID;
我们学到了什么?糟糕的数据库设计导致糟糕的查询。而且你可以用SQL做一些事情,这可能只是因为人们做不好的数据库设计而得到支持......:)