Попытка суммировать ряд строк на основе циклов отношения FK - PullRequest
0 голосов
/ 15 мая 2019

У меня есть таблица базы данных, которая содержит информацию о рассказах.
Я хотел бы иметь возможность суммировать все количество слов историй в серии / во всех сериях, чтобы получить «истинное» количество слов

Соответствующими столбцами макета таблицы являются StoryId, Title, Words, Prequel и Sequel.

например,

12345, 'The Hobbit', 95356, NULL, 54321
54321, 'The Fellowship of the Ring', 187790, 12345, 32145
32145, 'The Two Towers', 156198, 54321, 54123
54123, 'The Return of the King', 137115, 32145, NULL
13579, 'Some other book', 1234, NULL, NULL

Серия может содержать любое количество книг и всегда заканчивается NULL в столбце сиквела.

Я пытаюсь выбрать один из следующих вариантов:два результата.

  1. (специальный запрос выполняется для определенной истории)
StoryId, Title,      Words  Prequel Sequel Total
12345, 'The Hobbit', 95356, NULL, 54321, 474582

или (я подозреваю, что это проще, и я могу отфильтровать его позже)

(запрос выполняется по всей таблице)
StoryId, Title,      Words  Prequel Sequel Total
12345, 'The Hobbit', 95356, NULL, 54321, 474582
54321, 'The Fellowship of the Ring', 187790, 12345, 32145, 379226 (The sum of this and following stories)
32145, 'The Two Towers', 156198, 54321, 54123, 293313
54123, 'The Return of the King', 137115, 32145, NULL, 137115
13579, 'Some other book', 1234, NULL, NULL, 1234

Мне еще предстоит найти хороший способ сделать это с помощью чистого sql, пока я только что сделал вычисления в своей голове, но по мере роста базы данных она определенно не масштабируется.

1 Ответ

0 голосов
/ 15 мая 2019

Пожалуйста, сообщите нам о фактическом использовании этого решения: -)

Это было очень интересное и приятное испытание.

Вот решение:

WITH storyMap AS(
    SELECT
        s.storyId, s.Title, s.Words,
        NULL AS Prequel, s.Sequel, s.Words AS Total,
        convert(varchar(max), NULL) AS SeqTitles
    FROM dbo.story s
    WHERE s.Sequel IS NULL
    ----------
    UNION ALL
    ----------
    SELECT
        s.storyId, s.Title, s.Words,
        s.Prequel, s.Sequel, s.Words + sm.Total as Total,
        isnull(sm.SeqTitles + ' / ', '') + sm.Title AS SeqTitles
    FROM
        dbo.story s
            JOIN storyMap sm
            ON sm.storyId = s.Sequel
)
SELECT *
FROM storyMap sm

И результат для вашего образца:

storyId Title                       Words   Prequel Sequel  Total   SeqTitles
54123   The Return of the King      137115  NULL    NULL    137115  NULL
13579   Some other book             1234    NULL    NULL    1234    NULL
32145   The Two Towers              156198  54321   54123   293313  The Return of the King
54321   The Fellowship of the Ring  187790  12345   32145   481103  The Return of the King / The Two Towers
12345   The Hobbit                  95356   NULL    54321   576459  The Return of the King / The Two Towers / The Fellowship of the Ring

РЕДАКТИРОВАТЬ

Мое первое заданное решение агрегировано назад от последнего тома:

WITH storyMap AS(
    SELECT
        s.storyId, s.Title, s.Words,
        NULL AS Prequel, s.Sequel, s.Words AS Total,
        convert(varchar(max), NULL) AS SeqTitles
    FROM dbo.story s
    WHERE s.Prequel IS NULL
    ----------
    UNION ALL
    ----------
    SELECT
        s.storyId, s.Title, s.Words,
        s.Prequel, s.Sequel, s.Words + sm.Total as Total,
        isnull(sm.SeqTitles + ' / ', '') + sm.Title AS SeqTitles
    FROM
        dbo.story s
            JOIN storyMap sm
            ON sm.storyId = s.Prequel
)
SELECT *
FROM storyMap sm

Для вашегонапример, этот запрос приводит к

storyId Title                       Words   Prequel Sequel  Total   SeqTitles
12345   The Hobbit                  95356   NULL    54321   95356   NULL
13579   Some other book             1234    NULL    NULL    1234    NULL
54321   The Fellowship of the Ring  187790  12345   32145   283146  The Hobbit
32145   The Two Towers              156198  54321   54123   439344  The Hobbit / The Fellowship of the Ring
54123   The Return of the King      137115  32145   NULL    576459  The Hobbit / The Fellowship of the Ring / The Two Towers
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...