Мой ожидаемый результат довольно сложно объяснить, поэтому здесь я показал пример данных.
Исходная таблица: (у меня есть алфавиты в столбце 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
Я хочу объединить и вставить в одну отдельную единую таблицу.
@Cid: да, я меняю первую строку вывода,
@Larnu: да, формат всегда будет с 2 заглавными буквами и 4 цифрами... например, от AA0000 до ZZ9999





ЕСЛИ для каждой строки требуются значения 0-9999, тогда вам просто нужно ПЕРЕКРЕСТИТЬ СОЕДИНЕНИЕ с таблицей подсчета:
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; если это не так, то нам не хватает важной информации, которую следует включить в ваш вопрос.
Большое спасибо, ваш запрос выше работал в соответствии с моим требованием.
Попробуйте код ниже. Я использовал рекурсивный CTE, чтобы получить числа от 0 до 9999, а затем cross join добавить в ваш столбец 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)
Это не даст ожидаемых результатов. ОП хочет строки формата 'AA0000' Значение int0, приведенное к varchar(4), является значением '0', дающим окончательный результат 'AA0'. Кроме того, такой CTE является скрытой формой RBAR; итоговая таблица позволит избежать требования OPTION (MAXRECURSION 0) и, вероятно, обеспечит преимущество в производительности.
@Michał Turczyn использует Order by, чтобы получить ожидаемый результат.
Будет ли значение
Actual Codeвсегда иметь форматAA0000?