SQL: сортировка по имени домена электронной почты
каков самый короткий и / или эффективный оператор SQL для сортировки таблицы со столбцом адреса электронной почты по его фрагменту доменного имени?
это по существу игнорирует все, что находится перед " @ " в адресах электронной почты и без учета регистра. Давайте проигнорируем интернационализированные доменные имена для этого.
Target at: 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
EDIT:
Я не прошу ни одного оператора SQL, который будет работать на всех 3 или более SQL-движках. Любой вклад приветствуется. :)
13 ответов
попробуй такое
Запрос (Для Sql Server):
select * from mytbl
order by SUBSTRING(email,(CHARINDEX('@',email)+1),1)
Запрос(Для Oracle):
select * from mytbl
order by substr(email,INSTR(email,'@',1) + 1,1)
запрос(для MySQL)
pygorex1 already answered
выход:
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
Для MySQL:
select email, SUBSTRING_INDEX(email,'@',-1) AS domain from user order by domain desc;
для нечувствительных к регистру:
select user_id, username, email, LOWER(SUBSTRING_INDEX(email,'@',-1)) AS domain from user order by domain desc;
если вы хотите, чтобы это решение все, вам нужно не пытается извлечь вложенные столбцы. Функции в строке, как известно, медленно, как таблица становится все больше и больше.
на право вещь, котор нужно сделать в этом случае двинуть цену извлечения от select
(где это происходит много) в insert/update
где это происходит меньше (в большинстве обычных баз данных). Взяв на себя расходы только на insert
и update
, вы значительно увеличиваете общий эффективность базы данных, так как это только момент времени, когда вам нужно это сделать (т. е. это единственное время, когда данные меняются).
для этого разделите адрес электронной почты на два отдельных столбца в таблице,email_user
и email_domain
). Затем вы можете разделить его в своем приложении перед вставкой / обновлением или использовать триггер (или предварительно вычисленные столбцы, если ваша СУБД поддерживает его) в базе данных, чтобы сделать это автоматически.
затем вы Сортировать по email_domain
и, когда требуется полный адрес электронной почты, вы используете email_name|'@'|email_domain
.
кроме того, вы можете сохранить полный email
столбец и используйте триггер, чтобы дублировать только часть домена в email_domain
, тогда вам не нужно беспокоиться о конкатенации столбцов, чтобы получить полный адрес электронной почты.
вполне приемлемо вернуться из 3NF по соображениям производительности, если вы знаете, что делаете. В этом случае данные в двух столбцах не могут выйти из синхронизации просто потому, что триггеры этого не позволяют. Это хороший способ торговать дисковым пространством (относительно дешево) для производительности (мы всегда нужен).
и, если вы из тех, кто не любит возвращаться из 3NF вообще,email_name/email_domain
решение исправить это.
это также предполагая, что вы просто хотите обрабатывать адреса электронной почты вида a@b
- есть и другие действительные адреса электронной почты, но я не могу вспомнить ни одного из них в дикой природе годы.
для SQL Server можно добавить вычисляемый столбец к вашей таблице с извлечениями домена в отдельное поле. Если вы сохраняете этот столбец в таблице, вы можете использовать его как любое другое поле и даже поместить на него индекс, чтобы ускорить процесс, если вы много запрашиваете доменное имя:
ALTER TABLE Table1
ADD DomainName AS
SUBSTRING(email, CHARINDEX('@', email)+1, 500) PERSISTED
Итак, теперь ваша таблица будет иметь дополнительный столбец "DomainName", который содержит что-либо после знака " @ " в вашем адресе электронной почты.
предполагая, что вы действительно должны обслуживать MySQL, Oracle и MSSQL .. наиболее эффективным способом может быть сохранение имени учетной записи и доменного имени в двух отдельных полях. Вы можете сделать ваш заказ:
select id,name,email from table order by name
select id,name,email,account,domain from table order by email
select id,name,email,account,domain from table order by domain,account
как указывает Донни, функции манипуляции строками нестандартны .. вот почему вам придется сохранить данные избыточными!
Я добавил учетную запись и домен к третьему запросу, так как я шов, чтобы вспомнить не все DBMSs будет сортировать запрос на поле, которое не в выбранных полях.
для postgres запрос:
SELECT * FROM table
ORDER BY SUBSTRING(email,(position('@' in email) + 1),252)
значение 252
является самым длинным разрешенным доменом (так как максимальная длина электронной почты 254
включая местную часть,@
, и домен.
Посмотреть подробнее: какова максимальная длина действительного адреса электронной почты?
MySQL, интеллектуальная комбинация right () и instr ()
SQL Server,справа() и patindex ()
и, как сказал кто-то другой, если у вас есть достойный высокий счет записей, обернув поле электронной почты в функции в вас, где предложение сделает его таким образом, РСУБД не может использовать какой-либо индекс, который вы могли бы иметь в этом столбце. Итак, ты может потребоваться создать вычисляемый столбец, содержащий домен.
Это будет работать с Oracle:
select id,name,email,substr(email,instr(email,'@',1)+1) as domain
from table1
order by domain asc
мое предложение было бы (для mysql):
SELECT
LOWER(email) AS email,
SUBSTRING_INDEX(email, '@', + 1) AS account,
REPLACE(SUBSTRING_INDEX(email, '@', -1), CONCAT('.',SUBSTRING_INDEX(email, '.', -1)),'') -- 2nd part of mail - tld.
AS domain,
CONCAT('.',SUBSTRING_INDEX(email, '.', -1)) AS tld
FROM
********
ORDER BY domain, email ASC;
А затем просто добавьте где...исходный ответ для SQL Server не работал для меня....
вот версия для SQL Server...
select SUBSTRING(email,(CHARINDEX('@',email)+1),len(email)), count(*)
from table_name
group by SUBSTRING(email,(CHARINDEX('@',email)+1),len(email))
order by count(*) desc
работать умнее, а не тяжелее:
SELECT REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING(emails.email, POSITION('@' IN emails.email)+1)),'.',2)) FROM emails