Чтобы найти все страницы от первой страницы до последней страницы по идентификатору книги, ПРОСТАВЬТЕ номера своих страниц от 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
Для преобразования таблицы из трех столбцов (идентификатор, первая страница, последняя страница) в таблицу из двух столбцов (идентификатор, страница) потребуется 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 (что, как я полагаю, основано на названии книги). Ожидание.
Вот подробное объяснение почему " Random.nextInt (n)
и более эффективен, и менее предвзят, чем Math.random () * n
"из поста на форумах Sun, на который ссылается Гили:
Math.random () использует Random.nextDouble () для внутреннего использования.
Random.nextDouble () дважды использует Random.next (), чтобы сгенерировать дубль, который имеет приблизительно равномерно распределенные биты в своей мантиссе, поэтому он равномерно распределен в диапазоне от 0 до 1- (2 ^ -53).
Random.nextInt (n) использует Random.next () в среднем менее чем в два раза - он использует его один раз, и если полученное значение выше максимального кратного n ниже MAX_INT, он пытается снова, в противном случае возвращает значение по модулю n ( это предотвращает перекос распределения значений выше максимального кратного n ниже MAX_INT), таким образом, возвращая значение, которое равномерно распределено в диапазоне от 0 до n-1.
Перед масштабированием на 6 вывод Math.random () является одним из 2 ^ 53 возможных значений, полученных из равномерного распределения.
Масштабирование на 6 не изменяет количество возможных значений, и приведение к int затем приводит к принудительному переводу этих значений в одно из шести «сегментов» (0, 1, 2, 3, 4, 5), каждое из которых соответствует диапазоны, охватывающие 1501199875790165 или 1501199875790166 из возможных значений (так как 6 не является диспозитором 2 ^ 53). Это означает, что для достаточного количества бросков игральных костей (или кристалла с достаточно большим числом сторон) штамп покажет себя смещенным в сторону больших ведер.
Вы будете очень долго ждать бросания костей для этот эффект, чтобы показать.
Math. Функция random () также требует примерно вдвое больше обработки и подлежит синхронизации.
еще одним важным моментом является то, что Random.nextInt (n) повторяется, так как вы можете создать два объекта Random с помощью то же семя. Это невозможно с помощью Math.random ().
Согласно https://forums.oracle.com/forums/thread.jspa?messageID=6594485& # 6594485 Random.nextInt (n)
более эффективен и менее предвзят, чем Math.random () * n