ORDER BY
в подзапросе не имеет (гарантированного) эффекта. Это должно быть для самого внешнего запроса.
Либо используйте коррелированный подзапрос в предложении ORDER BY
.
SELECT ct.id,
ct.obj_id
FROM comment_thread ct
ORDER BY (SELECT count(*)
FROM comment_comment cc
WHERE cc.thread_id = ct.obj_id) DESC;
Или объединение и упорядочение по левому краю по объединенному количеству.
SELECT ct.id,
ct.obj_id
FROM comment_thread ct
LEFT JOIN (SELECT cc.thread_id,
count(*) count
FROM comment_comment cc
GROUP BY cc.thread_id) x
ON x.thread_id = ct.obj_id
ORDER BY x.count DESC
NULLS LAST;
Спецификации в вопросе не очень ясны, поэтому я просто предполагаю, что строка может содержать только буквы и цифры ASCII с дефисами, подчеркиванием и пробелами в качестве внутренних разделителей. Суть проблемы заключается в том, чтобы гарантировать, что первый и последний символы не являются разделителями и что в строке никогда не может быть более одного разделителя (в любом случае, эта часть кажется ясной). Вот самый простой способ:
/^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/
После сопоставления одного или нескольких буквенно-цифровых символов, , если есть разделитель, за ним необходимо следовать один или несколько буквенно-цифровых символов; повторяйте по мере необходимости.
Давайте посмотрим на регулярные выражения из некоторых других ответов.
/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/
По сути, это то же самое (при условии, что ваш вариант регулярного выражения поддерживает нотацию класса символов POSIX), но зачем делать разделитель необязательным? Единственная причина, по которой вы оказались в этой части регулярного выражения в первую очередь, - это наличие разделителя или другого недопустимого символа.
/^[a-zA-Z0-9]+([_\s\-]?[a-zA-Z0-9])*$/
С другой стороны, это работает только , потому что разделитель является необязательный. После первого разделителя он может соответствовать только одному буквенно-цифровому знаку. Чтобы соответствовать большему количеству совпадений, он должен повторять всю группу: нулевые разделители, за которыми следует один буквенно-цифровой, снова и снова. Если бы второй [a-zA-Z0-9]
сопровождался знаком плюс, он мог бы найти совпадение по гораздо более прямому маршруту.
/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/
При этом используется неограниченный просмотр назад, что очень редко особенность, но вы можете использовать опережающий поиск с тем же эффектом:
/^(?!.*[_\s-]{2,})[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9]$/
По сути, это выполняет отдельный поиск двух последовательных разделителей и не дает совпадения, если он находит один. Затем основной части нужно только убедиться, что все символы являются буквенно-цифровыми или разделителями, причем первый и последний являются буквенно-цифровыми. Поскольку эти два символа являются обязательными, имя должно состоять не менее чем из двух символов.
/^[a-zA-Z0-9]+([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*[a-zA-Z0-9]+$/
Это ваше собственное регулярное выражение, и оно требует, чтобы строка начиналась и заканчивалась двумя буквенно-цифровыми символами, а если в строке есть два разделителя, там между ними должно быть ровно два буквенно-цифровых символа. Таким образом, ab
, ab-cd
и ab-cd-ef
будут соответствовать, но a
, ab
и abc
не будет.
Кроме того, как отметили некоторые из комментаторов, (_ | - |)
в вашем регулярном выражении должно быть [-_]
. Эта часть не неверна , но если у вас есть выбор между чередованием и классом символов, вы всегда должны использовать класс символов: они более эффективны, а также более читабельны.
Опять же, Меня не беспокоит, должны ли «буквенно-цифровые» включать символы, отличные от ASCII, или точное значение «пробела», а просто как обеспечить соблюдение политики несмежных внутренних разделителей с помощью регулярного выражения.
По-моему, добавление ограниченного объема к этой модели было бы лучше
[a-zA-Z0-9] + ([_-]? [a-zA-Z0-9]) {5,40} $
([a-zA-Z0-9](_|-| )[a-zA-Z0-9])*
- это 0 или более повторений букв, пробелов, букв.
Таким образом, он будет соответствовать
a_aa_aa_a
, но не
aaaaa
Полное регулярное выражение не может соответствовать
a_aaaaaaaaa_a for example.
Давайте посмотрим назад к тому, что вы хотите:
* Usernames can consist of lowercase and capitals or alphanumerica characters
* Usernames can consist of alphanumeric characters
* Usernames can consist of underscore and hyphens and spaces
* Cannot be two underscores, two hypens or two spaces in a row
* Cannot have a underscore, hypen or space at the start or end
Начало простое ... просто сопоставьте буквенный знак, затем (введя два правила в строке) (буквенное или тире) * и снова и снова буквенный знак.
Чтобы чтобы предотвратить два тире подряд, вам, вероятно, нужно понимать lookahead / lookbehind.
О, и что касается другого ответа: пожалуйста, скачайте Espresso, он ДЕЙСТВИТЕЛЬНО помогает вам понять эти вещи.
Алфавитно-цифровые символы - это не просто [a-zA-Z0-9]
, это акцентированные, кириллические, греческие и другие буквы, которые можно использовать в имени пользователя.
(_ | - |)
можно заменить на [-_]
класс символов
Использование класса символов POSIX для буквенно-цифровых символов, чтобы заставить его работать с акцентированными и другими иностранными алфавитными символами:
/^[[:alnum:]]+([-_ ]?[[:alnum:]])*$/
Более эффективный (предотвращает захват):
/^[[:alnum:]]+(?:[-_ ]?[[:alnum:]]+)*$/
Они также предотвращают последовательности, превышающие один пробел / дефис / подчеркивание в комбинации. Из вашей спецификации не следует, желательно ли это, но ваше собственное регулярное выражение похоже, указывает на то, что вы хотите.
Еще одна рекомендация для Expresso 3.0 здесь - очень легко использовать и наращивать струны.
Регулярное выражение не работает. Самая сложная часть - это проверка на наличие следующих друг за другом пробелов / дефисов. Вы можете использовать это, которое использует ретроспективу:
/^[a-zA-Z0-9][a-zA-Z0-9_\s\-]*[a-zA-Z0-9](?<![_\s\-]{2,}.*)$/
Судя по всему, это правило не соответствует чему-то вроде «a_bc», «ab_c», «a_b» или "a_b_c".
Попробуйте: / ^ [a-zA-Z0-9] + ([_ \ s \ -]? [a-zA-Z0-9]) * $ /
что соответствует приведенным выше случаям, но не любой комбинации пробелов, тире или подчеркивания рядом друг с другом. Например: "_-" или "_" недопустимы.
Я предлагаю написать несколько модульных тестов, чтобы протестировать Regex. Это также поможет через несколько месяцев, когда вы обнаружите проблему с регулярным выражением и вам потребуется его обновить.