SQL - список всех страниц между записями с сохранением идентификатора ключа - PullRequest
2 голосов
/ 14 марта 2019

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

Пример ввода:

First Page  Last Page  ID
ABC_001     ABC_004    1
ABC_005     ABC_005    2
ABC_006     ABC_010    3

Конечный результат:

All Pages  ID
ABC_001    1
ABC_002    1
ABC_003    1
ABC_004    1
ABC_005    2
ABC_006    3
ABC_007    3
ABC_008    3
ABC_009    3
ABC_010    3

Любая помощь очень ценится. Я использую SQL mgm studio.

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

Один из подходов заключается в создании таблицы чисел , которая содержит список чисел, которые вы можете найти в содержимом столбца:

CREATE TABLE numbers( idx INTEGER);
INSERT INTO numbers VALUES(1);
INSERT INTO numbers VALUES(2);
...
INSERT INTO numbers VALUES(10);

Теперь, предполагая, что все значения страницы имеют 7 символов, причем последние 3 являются цифрами, мы можем JOIN исходную таблицу с таблицей numbers для генерации отсутствующих записей:

SELECT 
    CONCAT(
        SUBSTRING(t.First_Page, 1, 4), 
        REPLICATE('0', 3 - LEN(n.idx)),
        n.idx
    ) AS [ALl Pages],
    t.id
FROM
    mytable t
    INNER JOIN numbers n 
        ON  n.idx >= CAST(SUBSTRING(t.First_Page, 5, 3) AS int)
        AND n.idx <= CAST(SUBSTRING(t.Last_Page, 5, 3) AS int)

Это демонстрация на DB Fiddle с вашими примерами возвращаемых данных:

ALl Pages | id
:-------- | -:
ABC_001   |  1
ABC_002   |  1
ABC_003   |  1
ABC_004   |  1
ABC_005   |  2
ABC_006   |  3
ABC_007   |  3
ABC_008   |  3
ABC_009   |  3
ABC_010   |  3
1 голос
/ 14 марта 2019

Чтобы найти все страницы от Первой страницы до Последней страницы по идентификатору книги, ПРОКАЧИТЕ номера своих страниц от STRING до INTEGER, затем добавляйте +1 к каждому номеру страницы, пока не достигнете последней страницы.

Сначала превратите исходную таблицу в переменную таблицы с типами данных Integer, используя TRY_CAST.

DECLARE @Book TABLE (
    [ID]        INT
   ,[FirstPage] INT
   ,[LastPage]  INT
)

INSERT INTO @Book
SELECT  [ID]
       ,TRY_CAST(RIGHT([FirstPage], 3) AS int) AS [FirstPage]
       ,TRY_CAST(RIGHT([LastPage], 3) AS int)  AS [LastPage]
FROM [YourOriginalTable]

Установите максимальную страницу, на которую ваши страницы будут увеличиваться, используя переменную. Это сведет ваши результаты к правильному количеству страниц. В противном случае в вашей таблице будет гораздо больше строк, чем вам нужно.

DECLARE @LastPage   INT 
SELECT @LastPage = MAX([LastPage]) FROM @Book

Для преобразования таблицы из трех столбцов (ID, Первая страница, Последняя страница) в таблицу из двух столбцов (ID, Страница) потребуется UNPIVOT.

Мы заправляем этот UNPIVOT в CTE (Общее выражение таблицы: в основном, умная версия временной таблицы (например, #TempTable или @TableVariable, но которую вы можете использовать только один раз, и в некоторых случаях она немного более эффективна) обстоятельства).

В дополнение к UNPIVOT ваших столбцов [Имя] и [Фамилия] в большую таблицу, мы собираемся добавить любую другую комбинацию номера страницы для каждого идентификатора, используя UNION ALL.

;WITH BookCTE AS (
    SELECT [ID]
          ,[Page]
    FROM (SELECT [ID]
                ,[FirstPage]
                ,[LastPage]
          FROM @Book) AS bp
    UNPIVOT
    (
        [Page] FOR [Pages] IN ([FirstPage], [LastPage])
    ) AS up
    UNION ALL
    SELECT [ID], [Page] + 1 FROM BookCTE WHERE [Page] + 1 < @LastPage
)

Теперь, когда ваши данные хранятся в формате таблицы с использованием CTE со всеми комбинациями [ID] и [Page] вплоть до максимальной страницы в вашей таблице @Book, пришло время объединить ваш CTE с таблицей @Book.

SELECT DISTINCT
        cte.ID
       ,cte.Page
FROM BookCTE AS cte
    INNER JOIN @Book AS bk
        ON bk.ID = cte.ID
WHERE cte.Page <= bk.[LastPage]
ORDER BY
       cte.ID
      ,cte.Page
OPTION (MAXRECURSION 10000)

Смотри также:

Примечание: обновится с повторной интеграцией строковой части FirstPage и LastPage (что, как я полагаю, основано на названии книги). Ожидание.

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