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)
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)
如果您希望这个解决方案在所有的扩展,你应该不试图提取的子栏目.随着表越来越大,每行函数的速度非常慢.
在这种情况下,正确的做法是将提取成本select(发生在很多地方)转移到发生的insert/update地方(在大多数普通数据库中).通过仅招致的成本insert和update你大大提高数据库的整体效率,因为那是唯一的一次,你需要做的是点(即,它是唯一的时候,数据的变化).
为了实现此目的,请将电子邮件地址拆分为表中的两个不同列,email_user并且email_domain).然后,您可以在插入/更新之前将其拆分到应用程序中,或者在数据库中使用触发器(或者如果DBMS支持它,则使用预先计算的列)自动执行此操作.
然后你排序email_domain,当你想要完整的电子邮件地址时,你使用email_name|'@'|email_domain.
或者,您可以保留完整email列并使用触发器仅复制域部分email_domain,然后您永远不必担心连接列以获取完整的电子邮件地址.
如果您知道自己在做什么,那么出于性能原因从3NF恢复是完全可以接受的.在这种情况下,两列中的数据不能仅仅因为触发器不允许它而不同步.这是交换磁盘空间(相对便宜)以获得性能的好方法(我们总是想要更多).
并且,如果你不喜欢从3NF恢复,那么email_name/email_domain解决方案将解决这个问题.
这也假设您只想处理表单的电子邮件地址a@b- 还有其他有效的电子邮件地址,但我不记得在野外看到它们中的任何一个多年.