SQL:按电子邮件域名排序

o.k*_*k.w 19 sql sorting email sql-order-by domain-name

什么是使用DOMAIN名称片段对具有一列电子邮件地址的表进行排序的最短和/或最有效的SQL语句?

这基本上忽略了电子邮件地址中"@"之前的任何内容,并且不区分大小写.让我们忽略这个国际化的域名.

目标是:mySQL,MSSQL,Oracle

来自的样本数据 TABLE1

id   name           email 
------------------------------------------
 1   John Doe       johndoe@domain.com
 2   Jane Doe       janedoe@helloworld.com
 3   Ali Baba       ali@babaland.com
 4   Foo Bar        foo@worldof.bar.net
 5   Tarrack Ocama  me@am-no-president.org

通过电子邮件订购
SELECT * FROM TABLE1 ORDER BY EMAIL ASC

id   name           email 
------------------------------------------
 3   Ali Baba       ali@babaland.com
 4   Foo Bar        foo@worldof.bar.net
 2   Jane Doe       janedoe@helloworld.com
 1   John Doe       johndoe@domain.com
 5   Tarrack Ocama  me@am-no-president.org

按域名排序
SELECT * FROM TABLE1 ORDER BY ?????? ASC

id   name           email 
------------------------------------------
 5   Tarrack Ocama  me@am-no-president.org
 3   Ali Baba       ali@babaland.com
 1   John Doe       johndoe@domain.com
 2   Jane Doe       janedoe@helloworld.com
 4   Foo Bar        foo@worldof.bar.net

编辑:
我不是要求一个可以在所有3个或更多SQL引擎上工作的SQL语句.欢迎任何贡献.:)

pri*_*kar 21

试试这个

查询(适用于Sql Server):

select * from mytbl
order by SUBSTRING(email,(CHARINDEX('@',email)+1),1)
Run Code Online (Sandbox Code Playgroud)

查询(适用于Oracle):

select * from mytbl
order by substr(email,INSTR(email,'@',1) + 1,1)
Run Code Online (Sandbox Code Playgroud)

查询(适用于MySQL)

pygorex1 already answered
Run Code Online (Sandbox Code Playgroud)

输出:

ID名称电子邮件

5   Tarrack Ocama   me@am-no-president.org
3   Ali Baba    ali@babaland.com
1   John Doe    johndoe@domain.com
2   Jane Doe    janedoe@helloworld.com
4   Foo Bar foo@worldof.bar.net
Run Code Online (Sandbox Code Playgroud)

  • 对于Sql Server,它看起来只是对域的第一个字母进行排序,所以我调整如下:`通过SUBSTRING从mytbl顺序选择*(电子邮件,(CHARINDEX('@',电子邮件)+1) ,LEN(电子邮件)-CHARINDEX('@',电子邮件))` (4认同)

lee*_*ers 16

对于MySQL:

select email, SUBSTRING_INDEX(email,'@',-1) AS domain from user order by domain desc;
Run Code Online (Sandbox Code Playgroud)

对于不区分大小写的:

select user_id, username, email, LOWER(SUBSTRING_INDEX(email,'@',-1)) AS domain from user order by domain desc;
Run Code Online (Sandbox Code Playgroud)


pax*_*blo 8

如果您希望这个解决方案在所有的扩展,你应该试图提取的子栏目.随着表越来越大,每行函数的速度非常慢.

在这种情况下,正确的做法是将提取成本select(发生在很多地方)转移到发生的insert/update地方(在大多数普通数据库中).通过仅招致的成本insertupdate你大大提高数据库的整体效率,因为那是唯一的一次,你需要做的是点(即,它是唯一的时候,数据的变化).

为了实现此目的,请将电子邮件地址拆分为表中的两个不同列,email_user并且email_domain).然后,您可以在插入/更新之前将其拆分到应用程序中,或者在数据库中使用触发器(或者如果DBMS支持它,则使用预先计算的列)自动执行此操作.

然后你排序email_domain,当你想要完整的电子邮件地址时,你使用email_name|'@'|email_domain.

或者,您可以保留完整email列并使用触发器仅复制域部分email_domain,然后您永远不必担心连接列以获取完整的电子邮件地址.

如果您知道自己在做什么,那么出于性能原因从3NF恢复是完全可以接受的.在这种情况下,两列中的数据不能仅仅因为触发器不允许它而不同步.这是交换磁盘空间(相对便宜)以获得性能的好方法(我们总是想要更多).

并且,如果你不喜欢从3NF恢复,那么email_name/email_domain解决方案将解决这个问题.

这也假设您只想处理表单的电子邮件地址a@b- 还有其他有效的电子邮件地址,但我不记得在野外看到它们中的任何一个多年.