Генерация строк с индексом между двумя числами - PullRequest
3 голосов
/ 20 июля 2010

У меня есть одна таблица varchar, int, int, как это:

OS          MinSP      MaxSP
--          -----      -----
2000        4          4
XP          2          3
Vista       0          2
7           0          1

Мне нужен запрос, который сгенерирует список значений, подобных этому:

  • 2000 SP4
  • XP SP2
  • XP SP3
  • Vista
  • Vista SP1
  • Vista SP2
  • 7
  • 7 SP1

Редактировать

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

Ответы [ 3 ]

1 голос
/ 20 июля 2010
SELECT CASE WHEN MinSP = '0' THEN OS ELSE OS + ' SP' + cast(MinSP as 
    nvarchar(10)) END AS Results, MaxSP
FROM OS

UNION

SELECT CASE WHEN MaxSP = '0' THEN OS ELSE OS + ' SP' + cast(MaxSP as 
    nvarchar(10)) END AS Results, MaxSP
FROM OS
ORDER BY MaxSP DESC

EDIT:

И с учетом ваших новых критериев я предположил, что у вас будет вторая таблица с именем SPNums, которая заполнена таким количеством чисел, которое, по вашему мнению, вам нужно, начиная с 0.

SPNum
-----
   0
   1 
   2
   3
   4
   5
   6

А потом запрос:

SELECT CASE WHEN SPNum = '0' THEN OS ELSE OS + ' SP' + cast(SPNum as 
    nvarchar(10)) END AS Results
FROM OS
LEFT OUTER JOIN SPNums ON SPNum >= MinSP AND SPNum <= MaxSP
ORDER BY OS
1 голос
/ 21 июля 2010

Вам понадобится таблица Tally , чтобы сделать следующее, но она будет бить курсор и будет динамически расти со следующей выпущенной ОС. Ваш счетный стол тоже должен быть нулевым.

EDIT: исправлена ​​опечатка и добавлена ​​вторая версия

Версия 1 (у вас нет таблицы подсчета): Это создает таблицу чисел на лету, используя sys.all_columns. Есть много способов сделать это, но вы поняли идею.

;WITH    Tally(N)
          AS (SELECT    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1 --minus one to make this zero based
              FROM      sys.all_columns C)
    SELECT  OS + CASE WHEN N > 0 THEN ' SP' + CAST(B.N AS char(1))
                      ELSE ''
                 END
    FROM    dbo.Test A
    INNER JOIN Tally B ON B.N >= A.MinSp
                          AND B.N <= A.MaxSp

Вторая версия (у вас есть таблица подсчета, основанная на нуле):

SELECT  OS + CASE WHEN N > 0 THEN ' SP' + CAST(B.N AS char(1))
                  ELSE ''
             END
FROM    dbo.Test A
INNER JOIN dbo.Tally B ON B.N >= A.MinSp
                          AND B.N <= A.MaxSp
1 голос
/ 20 июля 2010

Быстрый ответ:

Select OS + ' SP' + Convert(varchar(50),MinSp) as col1 from TABLE
UNION 
Select OS + ' SP' + Convert(varchar(50),MaxSp) as col1 from TABLE

Добавьте ORDER BY по желанию.

Но посмотрите и мой комментарий к вашему вопросу.

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