Объединение / свертывание строк с group_by + условно для столбца для следующей строки - PullRequest
1 голос
/ 13 апреля 2020

У меня есть чат от телекоммуникационной компании, подписывающий новых клиентов. В чате у клиента и представителя компании есть чат.

Я пытаюсь свернуть чат, чтобы было меньше строк. Диаграммы ниже показывают, как выглядят данные до и как должны выглядеть данные после.

ДО

Dataset right now

ПОСЛЕ

What I would like to see

Я просмотрел следующие статьи:

Я пробовал этот код:

select 
    unique_id, string_agg(concat(text, ' ', text), ', ')
from 
    conversation
group by 
    unique_id, user

Однако, это не свернет его по мере необходимости. Он сворачивается полностью до 2х строк: одна для клиента, другая для компании. Лог c Я ищу, если следующая строка в этом запросе содержит тот же уникальный_идентификатор пользователя. Затем объединить текстовое поле текущей строки с текстовым полем следующей строки.

Вот SQL Скрипка страницы, но я запускаю этот код на SQL сервере, который имеет string_agg: http://sqlfiddle.com/#! 9 / 5ad86c / 3

Я запросил почти аналогичный алгоритм в R, если вы посмотрите мою историю StackOverflow.

CREATE TABLE conversation
(
     `unique_id` double, 
     `line_no` int, 
     `user` varchar(7000), 
     `text` varchar(7000)
);

INSERT INTO conversation (`unique_id`, `line_no`, `user`, `text`)
VALUES
    (50314585222, 1, 'customer', 'Hi I would like to sign up for a service'),
    (50314585222, 2, 'company', 'Hi My name is Alex. We can offer the following plans. We also have signup bonuses, with doubling of data for 12 months '),
    (50314585222, 3, 'company', 'Plan1: 40GB data, with monthly price of $80'),
    (50314585222, 4, 'company', 'Plan2: 20GB data, with monthly price of $40'),
    (50314585222, 5, 'company', 'Plan3: 5GB data, with monthly price of $15'),
    (50314585222, 6, 'customer', 'I was hoping for a much smaller plan, with only voice service'),
    (50314585222, 7, 'customer', 'maybe the $10 per month plan.'),
    (50319875222, 4, 'customer', 'so how do I sign up'),
    (50319875222, 5, 'customer', '*for the service'),
    (50319875222, 7, 'company', 'maybe I can call you for your details?')
;

Ответы [ 2 ]

1 голос
/ 13 апреля 2020

Если я вас правильно понимаю, следующий подход - это возможное решение. Вам нужно найти изменения и определить соответствующие группы:

Таблица:

CREATE TABLE [conversation]
(
     [unique_id] bigint, 
     [line_no] int, 
     [user] varchar(7000), 
     [text] varchar(7000)
);

INSERT INTO [conversation] ([unique_id], [line_no], [user], [text])
VALUES
    (50314585222, 1, 'customer', 'Hi I would like to sign up for a service'),
    (50314585222, 2, 'company', 'Hi My name is Alex. We can offer the following plans. We also have signup bonuses, with doubling of data for 12 months '),
    (50314585222, 3, 'company', 'Plan1: 40GB data, with monthly price of $80'),
    (50314585222, 4, 'company', 'Plan2: 20GB data, with monthly price of $40'),
    (50314585222, 5, 'company', 'Plan3: 5GB data, with monthly price of $15'),
    (50314585222, 6, 'customer', 'I was hoping for a much smaller plan, with only voice service'),
    (50314585222, 7, 'customer', 'maybe the $10 per month plan.'),
    (50319875222, 4, 'customer', 'so how do I sign up'),
    (50319875222, 5, 'customer', '*for the service'),
    (50319875222, 7, 'company', 'maybe I can call you for your details?')
;

Заявление:

; WITH ChangesCTE AS (
    SELECT 
        *,
        LAG([user]) OVER (PARTITION BY [unique_id] ORDER BY [line_no]) AS prev_user
    FROM [conversation]
), GroupsCTE AS (
    SELECT 
        *,
        SUM(CASE WHEN [user] <> [prev_user] OR [prev_user] IS NULL THEN 1 ELSE 0 END) OVER (PARTITION BY [unique_id] ORDER BY [line_no]) AS [group_id]
    FROM ChangesCTE
)
SELECT 
    [unique_id], 
    MIN([line_no]) AS [line_no], 
        MIN([user]) AS [user], 
        STRING_AGG([text], ' ') WITHIN GROUP (ORDER BY [line_no]) AS [text]
FROM GroupsCTE
GROUP BY [unique_id], [group_id]
ORDER BY [unique_id]

Результат:

unique_id   line_no user        text
50314585222 1       customer    Hi I would like to sign up for a service
50314585222 2       company     Hi My name is Alex. We can offer the following plans. We also have signup bonuses, with doubling of data for 12 months  Plan1: 40GB data, with monthly price of $80 Plan2: 20GB data, with monthly price of $40 Plan3: 5GB data, with monthly price of $15
50314585222 6       customer    I was hoping for a much smaller plan, with only voice service maybe the $10 per month plan.
50319875222 4       customer    so how do I sign up *for the service
50319875222 7       company     maybe I can call you for your details?
0 голосов
/ 13 апреля 2020

Это проблемы пробелов и островов, когда вы хотите сгруппировать смежные строки по одному и тому же говорящему.

Чтобы это можно было решить, вам нужен столбец для упорядочения записей. Кажется, мы не можем использовать line_no, который имеет повторяющиеся значения в одном разговоре. Я все еще предполагал, что такой столбец существует и называется ordering_col.

select
    unique_id,
    min(line_no) line_no,
    user,
    string_agg(text) within group(order by ordering_id) text
from (
    select 
        t.*,
        row_number() over(partition by unique_id order by ordering_id) rn1,
        row_number() over(partition by unique_id, user order by ordering_id) rn2
    from mytable t
) t
group by unique_id, user, rn1 - rn2
order by unique_id, min(ordering_id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...