цикл в программе SQL Server с таблицей - PullRequest
0 голосов
/ 19 февраля 2019

Мой ожидаемый результат довольно сложно объяснить, поэтому здесь я показал примеры данных.

SourceTable : (У меня есть алфавиты в столбце HeadNo)

HeadNo   |   Start   |   End
---------+-----------+----------
   AA    |   AA0000  | AA9999
   AB    |   AB0000  | AB9999
   AC    |   AC0000  | AC9999
   AD    |   AD0000  | AD9999
    --------------------
    --------------------
    ------- so on ------
   ZZ    |   ZZ0000  | ZZ9999

Из этой исходной таблицы я хочу создать вид результата цикла, где каждый HeadNo будет возвращать 10000 результат для каждого, начиная с 0000 до 9999.

Результат должен выглядеть примерно так: :

HeadNo   |   Actual Code
---------+---------------
   AA    |   AA0000
   AA    |   AB0001
   AA    |   AC0002
   AA    |   AD0003
    --------------------
    --------------------
    ------- so on ------
   AA    |   AA9998
   AA    |   AA9999

одинаково для каждого HeadNo

   ZZ    |   ZZ0000
   ZZ    |   ZZ0001
   ZZ    |   ZZ0002
   ZZ    |   ZZ0003
    --------------------
    --------------------
    ------- so on ------
   ZZ    |   ZZ9999

Я хочу объединить и вставить в одну отдельную таблицу.

Ответы [ 2 ]

0 голосов
/ 19 февраля 2019

Попробуйте код ниже.Я использовал рекурсивный CTE для получения чисел от 0 до 9999, а затем cross join ed для вашего HeadNo столбца:

;with cte as (
  select 0 n
  union all 
  select n + 1 from cte
  where n < 9999
)

select HeadNo, HeadNo + right('0000' + cast(n as varchar(4)), 4) from MyTable
cross join cte option (maxrecursion 0)
0 голосов
/ 19 февраля 2019

IF каждая строка требует значений 0-9999, тогда вам просто нужно CROSS JOIN присоединиться к таблице подсчета:

WITH N AS(
    SELECT *
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4 --10000
    )
SELECT YT.HeadNo,
       YT.HeadNo + RIGHT('0000' + CONVERT(varchar(4),T.I),4) AS ActualCode
FROM YourTable YT
     CROSS JOIN Tally T;

Если, однако, у вас есть фактические начальный и конечный диапазоныдля HeadNo (как в примере ниже), вам нужно будет использовать немного больше логики в JOIN:

WITH VTE AS (
    SELECT *
    FROM (VALUES('AA','AA0000','AA9999'),
                ('AB','AB0000','AB5000'), --Guesssing this is more realistic
                ('AC','AC1000','AC8000'), 
                ('AD','AD0000','AD0100'),
                ('ZZ','ZZ0000','ZZ9999')) V(HeadNo, HeadStart, HeadEnd)),
N AS(
    SELECT *
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
    FROM N N1
         CROSS JOIN N N2 --100
         CROSS JOIN N N3 --1000
         CROSS JOIN N N4 --10000
    )
SELECT V.HeadNo,
       V.HeadNo + RIGHT('0000' + CONVERT(varchar(4),T.I),4) AS ActualCode
FROM VTE V
     JOIN Tally T ON T.I BETWEEN STUFF(V.HeadStart,1,2,'') AND STUFF(V.HeadEnd,1,2,'')
ORDER BY V.HeadNo,
         ActualCode;

Во втором примере предполагается , что HeadNoвсегда будет иметь формат AA0000;в противном случае мы упускаем важную информацию, которая должна быть включена в ваш вопрос.

...