Количество указано c символов в столбце - PullRequest
0 голосов
/ 27 апреля 2020

У меня есть таблица со списком заголовков. Я пытаюсь найти способ создания запроса подстроки, который позволит мне подсчитать, сколько раз определенный символ встречается во всем столбце. Например, сколько раз встречается буква «А»? Я думаю о подстроке, так как я хочу узнать количество букв A - I.

Мне нужна новая таблица, которая показывает буквы подстроки (скажем, AZ) и рядом с ними общее количество раз, которое эта буква встречается во всем столбце (а не только в каждом ряду).

1 Ответ

0 голосов
/ 27 апреля 2020

Для базовых c ASCII букв, таких как AZ (как упомянуто) и (типичная) кодировка UTF-8 или LATIN * (или большинство других):

SELECT chr(c) AS letter
     , sum(octet_length(col)
         - octet_length(translate(col, chr(c), ''))) AS total_count
FROM   generate_series (ascii('A'), ascii('Z')) c
CROSS  JOIN tbl
GROUP  BY 1;

translate() работает для односимвольных замен и немного быстрее, чем replace() - который вы будете использовать для поиска многосимвольных строк.

In ( типично) кодировка UTF-8 или LATIN *, буквы c ASCII представлены одним байтом. Это позволяет более быструю функцию octet_length(). Для подсчета символов, закодированных большим количеством байтов, вместо этого используйте length(), который подсчитывает символы вместо байтов.

Кроме того, мы можем удобно генерировать диапазон букв, таких как AZ, с generate_series(), потому что их байтовое представление выстраивается в непрерывном диапазоне в упомянутых кодировках. Преобразовать в integer с помощью ascii() и обратно с chr().

Затем CROSS JOIN к вашему столу (tbl), измерить разницу между исходной длиной и после удаления буквы интереса и суммой.

Но при подсчете многих символов в ваших строках этот альтернативный подход , вероятно, намного быстрее :

SELECT letter, count(*) AS total_count
FROM   tbl, unnest(string_to_array(col, NULL)) letter
WHERE  ascii(letter) BETWEEN ascii('A') AND ascii('Z')
GROUP  BY 1;

Для подсчета без учета регистра введите lower() или upper():

FROM   tbl, unnest(string_to_array(upper(col), NULL)) letter

Чтобы проверить наличие нескольких непостоянных диапазонов символов:

WHERE  letter ~ '^[a-zA-Z]$'  -- a-z and A-Z separately (case-sensitive)

Или случайный выбор:

WHERE  'abcXYZ' ~ letter

string_to_array() с разделителем NULL разбивает строку на массив из отдельных символов, unnest() (используя неявный CROSS JOIN LATERAL), отфильтруйте интересующие вас (опять же, используя их байтовое представление, чтобы сделать это быстро. Затем просто посчитайте за символ.

Связанный:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...