2012-04-20 3 views
2

私はちょうど私が就職の面接で尋ねられるなら、私はそれについて完全に無知ではないので、ちょうどSQLで少し遊んでいます。私の友人は最近インタビューで次の質問を聞かれました。彼はそれを手に入れることができませんでした。SQLをうまく知っていて、彼が知らなかった仕事の誰かに尋ねました。あなたは私のためにこの問題に答えることができますか?お願いします?標準化されていない列を別々のレコードに選択しますか?

* 問題 *

データベースの正規化(または正規化の欠如)は、多くの場合、開発者のための課題を提示しています。

は、3つのフィールドが含まれている従業員のデータベーステーブルを考えてみましょう:

EmployeeID 
EmployeeName 
EmailAddresses 

ユニークな社員によって識別されるすべての従業員は、1つまたは複数のカンマで区切られた、@ rockauto.com電子メールアドレスを持っていることEmailAddressesフィールド。

データベーステーブルは以下に定義される:テスト目的のために

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', '[email protected]'), 
('2', 'Fred', '[email protected],[email protected]'), 
('3', 'Fred', '[email protected]mpanyx.com'), 
('4', 'Joe', '[email protected],[email protected]'); 

あなたの仕事は、次のように表示され、単一のMySQL SELECTクエリを記述することです上記のサンプルデータの出力:

Employee EmailAddress 
Bill [email protected] 
Fred (2) [email protected] 
Fred (2) [email protected] 
Fred (3) [email protected] 
Joe  [email protected] 
Joe  [email protected] 

同じ名前の複数の人物(この場合は「フレッド」)が存在するため、EmployeeIDがカッコ内に含まれています。

クエリは、MySQLバージョン5.1.41互換構文で記述する必要があります。 ORDER BY EmployeeID ASC "

この問題では、単一のSQL SELECTクエリを送信する必要があります。あなたのクエリは、合理的な時間内に1000レコードのテーブルを処理できる必要があります。

+9

これはひどいインタビューの質問です。 – bobwienholt

+0

私たちは、select文を解析するためにphpを使用することを許可されていますか、またはその形式で直接クエリを引き出す必要がありますか? – squarephoenix

+2

このデータベース構造を正規化する方法はより良い質問です^^ –

答えて

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; 

EDIT:以下役に立たない数字で

が生成:

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を使って作業を行うことができます:)

+0

電子メールのフィールドは40文字しかないので、そこには10イベントは収まりません。 –

+0

良い点...数字の生成が大幅に簡素化される可能性があります。明らかに、MySQLでパラメータ化された行数を生成する方法はありません。 – Toni

関連する問題