Подсчет повторяющихся шаблонов символов в строке с использованием MySQL

Дана строка в примерной таблице как:

Столбец А abcccaaaaddeeaabbaa

Как мы можем получить следующий вывод, используя MYSQL?

последовательность явления аааа 1 ссс 1 дд 1 эээ 1 аа 2 бб 1 а 1 б 1

Пытался вычислить это с помощью MySQL. Невозможно получить правильную логику для того же самого.

Обновлено: Моя последняя попытка с BigQuery:

WITH Input AS (
  SELECT 'abcccaaaaddeeaabbaa' AS str
),

Exploded AS (
  SELECT 
    SUBSTR(str, pos, 1) AS char,
    pos,
    LAG(SUBSTR(str, pos, 1)) OVER (ORDER BY pos) AS prev_char
  FROM Input, 
  UNNEST(GENERATE_ARRAY(1, LENGTH(str))) AS pos
),

Grouped AS (
  SELECT
    char,
    pos,
    IF(char = prev_char, 0, 1) AS new_group
  FROM Exploded
),

Sequenced AS (
  SELECT
    char,
    pos,
    SUM(new_group) OVER (ORDER BY pos) AS sequence_id
  FROM Grouped
),

Aggregated AS (
  SELECT
    sequence_id,
    STRING_AGG(char, '' ORDER BY pos) AS sequence
  FROM Sequenced
  GROUP BY sequence_id
),

FinalCounts AS (
  SELECT
    sequence,
    COUNT(*) AS occurrences
  FROM Aggregated
  GROUP BY sequence
)
select * from FinalCounts

База данных на самом деле не является подходящим инструментом для этого. Почему вы пытаетесь сделать это в MySQL?

Tim Biegeleisen 20.06.2024 06:08

@TimBiegeleisen: Похоже, это один из вопросов, недавно возникших в интервью. Захотелось еще раз попробовать то же самое.

sqlmnk 20.06.2024 06:13

Хранимая процедура, перебирает строку по каждому символу, проверяет, совпадает ли она с предыдущей. Если это не так, вставьте шаблон во временную таблицу. В конце сделайте выбор во временной таблице с помощью счетчика и группировки. Но мой ответ — вообще не делать этого в MySQL.

Shadow 20.06.2024 07:40

Неужели «Столбец А» на самом деле не является именем столбца? Покажите фактические имена таблиц и столбцов, которые вы используете.

ysth 20.06.2024 08:02

Не удаляйте этот пост @sqlmnk из-за отрицательного голосования. Потому что ответ ysth потрясающий...

Art Bindu 20.06.2024 12:16

bigquery — это не MySQL. пожалуйста, не отмечайте вопросы bigquery mysql и не используйте bigquery для проверки sql для mysql

ysth 20.06.2024 21:08

@ysth: Это не большой вопрос, а вопрос для MySQL. Просто хотел опубликовать метод, который, как я обнаружил, был близок к решаемому для меня. Предполагается, что ответ будет в MySQL.

sqlmnk 21.06.2024 01:05
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
7
99
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Разделите его на одну строку для каждого символа, затем определите серии символов и суммируйте их:

with recursive chars as (
  select bar,
    char_length(bar) idx,
    substr(bar, -1) ch
  from foo

  union all

  select bar, idx-1, substr(bar,idx-1,1)
  from chars
  where idx > 1
),
charruns as (
  select ch, idx,
    count(1) over (order by idx)
      - count(1) over (partition by ch order by idx)
      run_id
  from chars
),
runs as (
  select
    repeat(ch, count(1)) sequence,
    min(idx) idx
  from charruns
  group by ch, run_id
),
occurrences as (
  select
    sequence,
    count(1) occurrences,
    min(idx) idx
  from runs
  group by sequence
)
select sequence, occurrences
from occurrences
order by char_length(sequence) desc, idx

рабочий пример

🫡My Hat's off to you! @ysth. Я проверил ваш ответ, это действительно потрясающе, как вы думаете и решаете проблему с помощью SQL-запроса.

Art Bindu 20.06.2024 12:13

вот более короткий запрос

SET @in = 'abcccaaaaddeeaabbaa';

WITH RECURSIVE cte AS (
    SELECT CAST(REGEXP_SUBSTR(@in, '^(.)\\1*') AS CHAR CHARACTER SET utf8mb4) AS prefix,
           CAST(REGEXP_REPLACE(@in, '^(.)\\1*', '') AS CHAR CHARACTER SET utf8mb4) AS modified_string,
           1 AS step
    UNION ALL
    SELECT CAST(REGEXP_SUBSTR(modified_string, '^(.)\\1*') AS CHAR CHARACTER SET utf8mb4) AS prefix,
           CAST(REGEXP_REPLACE(modified_string, '^(.)\\1*', '') AS CHAR CHARACTER SET utf8mb4) AS modified_string,
           step + 1 AS step
    FROM cte
    WHERE modified_string != '' AND REGEXP_SUBSTR(modified_string, '^(.)\\1*') IS NOT NULL
)
SELECT prefix as sequence,
       SUM(1) as occurrences
FROM cte
GROUP BY prefix
ORDER BY LENGTH(prefix) DESC, prefix;

результат:

sequence    occurrences
aaaa    1
ccc     1
aa      2
bb      1
dd      1
ee      1
a       1
b       1   

образец dbfiddle

образец с таблицей dbfiddle

Другие вопросы по теме