2

私はSQLを少しいじっているので、就職の面接で尋ねられたとしても、SQLについて完全に無知というわけではありません。私の友人は最近、インタビューで次の質問をされましたが、彼はそれを理解できませんでした.SQLをきちんと知っている職場の人に尋ねましたが、彼は知りませんでした. この問題に答えて、それがどのように機能するか説明してもらえますか? お願いします?

*問題*

データベースの正規化 (または正規化の欠如) は、多くの場合、開発者にとって課題となります。

次の 3 つのフィールドを含む従業員のデータベース テーブルを考えてみましょう。

EmployeeID
EmployeeName
EmailAddresses

一意の EmployeeID で識別されるすべての従業員は、EmailAddresses フィールドに 1 つ以上のカンマ区切りの @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

同姓同名(この場合は「フレッド」)が複数存在するため、カッコ内にEmployeeIDが含まれていることに注意してください。

クエリは、MySQL バージョン 5.1.41 互換の構文で記述する必要があります。順序付けは、標準的なデータベースの昇順である「ORDER BY EmployeeID ASC」を使用して行われると想定する必要があります。

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

4

1 に答える 1

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で何かをすることができます、それはおそらく人々が貧弱なデータベース設計をしているという理由だけでサポートされています... :)

于 2012-04-20T18:03:56.383 に答える