sql >> データベース >  >> RDS >> Mysql

非正規化された列を個別のレコードに選択しますか?

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




    1. Dockerコンテナごとに1つまたは複数のデータベース

    2. Zend_Db_Selectの順序をランダムに選択し、mssql/mysqlと互換性があります

    3. エラーメッセージのないエラーをデバッグするにはどうすればよいですか?

    4. PL/pgSQL関数のオプションの引数