Сводная таблица SQL: выбор следующего доступного числа - PullRequest
0 голосов
/ 02 декабря 2010

Мне нужно найти следующий доступный номер в наборе:

select min([pivot])
from   [pivot]
where not exists (
      select null as nothing
      from   product
      where  product.id = [pivot].[pivot])

Однако это приложение будет использоваться очень долго, и поле [pivot] является целым числом.Я действительно не хочу создавать 2 147 483 647 записей [pivot] (последовательные числа от нуля до большого числа в таблице).Создание представления занимает слишком много времени.

Существует ли какая-либо функция в T-SQL (Microsoft SQL Server 2005/2008), которая может предоставить таблицу [pivot] без ее фактического создания.Создание [сводного] представления является плохим, поскольку для доступа к представлению требуется много времени.

Ответы [ 3 ]

3 голосов
/ 02 декабря 2010

Посмотрите, сработает ли что-то подобное для вас.В моем примере #Test имеет отверстие 5, которое должно быть возвращено, второе (# Test2) не имеет отверстий, поэтому мы ожидаем, что будет возвращен новый идентификатор.Это делается путем самостоятельного присоединения к себе.Я не уверен, почему у вас там разворот, поэтому я могу неправильно понять вашу проблему.

CREATE TABLE #test
(
    num int
)

CREATE TABLE #test2
(
    num int
)

INSERT INTO #test (num)
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 6 UNION ALL
SELECT 7 

INSERT INTO #test2 (num)
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL 
SELECT 7

SELECT MIN(t1.num)+1 FROM #test t1
    LEFT JOIN #test t2 ON t1.num+1 = t2.num
    WHERE t2.num IS NULL

SELECT MIN(t1.num)+1 FROM #test2 t1
    LEFT JOIN #test2 t2 ON t1.num+1 = t2.num
    WHERE t2.num IS NULL
1 голос
/ 03 декабря 2010

Я не уверен, что это лучший способ сделать это, но он отвечает на главный вопрос об автоматическом создании таблицы:

WITH myValueTable AS (
    SELECT 1 AS 'val'
    UNION ALL
    SELECT val + 1 FROM myValueTable WHERE val < 1000
)
SELECT * FROM myValueTable OPTION (MAXRECURSION 1000)

... который вернет таблицу из одного столбца со значениями от 1 до 1000. Однако, если вы собираетесь делать это регулярно, будет быстрее (для всего запроса) создать статическую таблицу. Если вы можете закрепить значения до заданного диапазона, например, начиная с 124 и сгенерировать следующие 10, это будет улучшением.

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

Изменить ... Если вы пытаетесь найти «пробел» в наборе чисел, вы можете попробовать:

WITH mycte AS (
    SELECT product.id, ROW_NUMBER() OVER (ORDER BY product.id) AS 'rownum' FROM product
    UNION
    SELECT MAX(product.id), MAX(product.id) + 1 FROM product
)
SELECT MIN(rownum) FROM mycte WHERE rownum <> id

... опять же не может гарантировать производительность, но может дать вам идеи для игры.

0 голосов
/ 02 декабря 2010
select min([pivot]) + 1 as next_num

?

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