Подтвердить что ты не робот

SQL: сортировка по имени домена электронной почты

Каков самый короткий и/или эффективный оператор SQL для сортировки таблицы с столбцом адреса электронной почты с помощью фрагмента имени DOMAIN?

Это по сути игнорирует все, что есть до "@" в адресах электронной почты и без учета регистра. Пусть игнорируют интернационализированные имена доменов для этого.

Целевая задача: mySQL, MSSQL, Oracle

Пример данных из TABLE1

id   name           email 
------------------------------------------
 1   John Doe       [email protected]
 2   Jane Doe       [email protected]
 3   Ali Baba       [email protected]
 4   Foo Bar        [email protected]
 5   Tarrack Ocama  [email protected]

Заказ по электронной почте
SELECT * FROM TABLE1 ORDER BY EMAIL ASC

id   name           email 
------------------------------------------
 3   Ali Baba       [email protected]
 4   Foo Bar        [email protected]
 2   Jane Doe       [email protected]
 1   John Doe       [email protected]
 5   Tarrack Ocama  [email protected]

Заказ по домену SELECT * FROM TABLE1 ORDER BY ?????? ASC

id   name           email 
------------------------------------------
 5   Tarrack Ocama  [email protected]
 3   Ali Baba       [email protected]
 1   John Doe       [email protected]
 2   Jane Doe       [email protected]
 4   Foo Bar        [email protected]

EDIT:
Я не прошу ни одного оператора SQL, который будет работать на всех трех или более SQL-машинах. Любые вклады приветствуются.:)

4b9b3361

Ответ 1

Попробуйте это

Запрос (для сервера Sql):

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 name email

5   Tarrack Ocama   [email protected]
3   Ali Baba    [email protected]
1   John Doe    [email protected]
2   Jane Doe    [email protected]
4   Foo Bar [email protected]

Ответ 2

Для 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;

Ответ 3

Если вы хотите, чтобы это решение вообще масштабировалось, вы не должны пытаться извлекать под-столбцы. Функции в строке заведомо медленны, так как таблица становится все больше и больше.

Правильная вещь в этом случае - переместить стоимость извлечения из select (где это происходит много) на insert/update, где это происходит меньше (в большинстве обычных баз данных). Исходя из стоимости только на insert и update, вы значительно увеличиваете общую эффективность базы данных, так как это единственный момент времени, когда вам нужно это делать (т.е. Это единственный раз, когда данные меняются).

Чтобы достичь этого, разделите адрес электронной почты на два разных столбца в таблице, email_user и email_domain). Затем вы можете разбить его в своем приложении перед вставкой/обновлением или использовать триггер (или предварительно вычисленные столбцы, если ваша СУБД поддерживает его) в базе данных, чтобы сделать это автоматически.

Затем вы сортируете по email_domain и, если вам нужен полный адрес электронной почты, вы используете email_name|'@'|email_domain.

В качестве альтернативы вы можете сохранить полный столбец email и использовать триггер для дублирования только части домена в email_domain, тогда вам не нужно беспокоиться о конкатенации столбцов, чтобы получить полный адрес электронной почты.

Это совершенно приемлемо для возврата из 3NF по соображениям производительности, если вы знаете, что делаете. В этом случае данные в двух столбцах не могут выйти из синхронизации просто потому, что триггеры не позволяют этого. Это хороший способ обмена дисковым пространством (относительно дешевым) для производительности (мы всегда хотим большего).

И если вы не любите возвращаться от 3NF вообще, решение email_name/email_domain исправит это.

Это также предполагает, что вы просто хотите обрабатывать адреса электронной почты формы [email protected] - есть другие допустимые адреса электронной почты, но я не могу вспомнить, что они виделись в дикой природе в течение многих лет.

Ответ 4

Для SQL Server вы можете добавить вычисленный столбец в свою таблицу с извлечением домена в отдельное поле. Если вы сохраняете этот столбец в таблице, вы можете использовать его, как и любое другое поле, и даже индексировать его, чтобы ускорить процесс, если вы часто запрашиваете доменное имя:

ALTER TABLE Table1
  ADD DomainName AS 
     SUBSTRING(email, CHARINDEX('@', email)+1, 500) PERSISTED

Итак, теперь ваша таблица будет иметь дополнительный столбец "DomainName", который содержит что-либо после знака "@" на вашем адресе электронной почты.

Ответ 5

Предполагая, что вы действительно должны обслуживать 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

как указывает Донни, функции манипуляции строкой не являются стандартными.. поэтому вам придется сохранять данные избыточными!

Я добавил учетную запись и домен в третий запрос, так как я швы напомню, что не все СУБД будут сортировать запрос в поле, которое не находится в выбранных полях.

Ответ 6

Для postgres запрос:

SELECT * FROM table
ORDER BY SUBSTRING(email,(position('@' in email) + 1),252)

Значение 252 является самым длинным разрешенным доменом (поскольку максимальная длина электронной почты 254, включая локальную часть, @ и домен.

См. это для получения дополнительной информации: Какова максимальная длина действительного адреса электронной почты?

Ответ 7

Вам нужно будет использовать функции манипуляции текстом для анализа домена. Затем упорядочитесь по новому столбцу.

Ответ 8

MySQL, интеллектуальная комбинация right() и instr()

SQL Server, right() и patindex()

Oracle, instr() и substr()

И, как сказал кто-то другой, если у вас есть достойный показатель высокой записи, обертывание поля электронной почты в функции в вас, где предложение сделает так, чтобы СУРБД не могли использовать какой-либо индекс, который может иметься в этом столбце. Таким образом, вы можете захотеть создать вычисляемый столбец, который содержит домен.

Ответ 9

Если у вас есть миллион записей, я предлагаю вам создать новый столбец только с именем домена.

Ответ 10

Это будет работать с Oracle:

select id,name,email,substr(email,instr(email,'@',1)+1) as domain
from table1
order by domain asc

Ответ 11

Мое предложение было бы (для 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;

Ответ 12

Исходный ответ для 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

Ответ 13

работать умнее не сложнее:

SELECT REVERSE(SUBSTRING_INDEX(REVERSE(SUBSTRING(emails.email, POSITION('@' IN emails.email)+1)),'.',2)) FROM emails