我需要创建一个带有标识符列的表。标识符数据由3部分组成,第一部分是字母[A-Z],第二部分是数字[1-42],第三部分是数字[1-6]。
我想知道最快最好的方法,因为我真的被卡住了。输出应如下所示:
A-1-1
A-1-2
A-1-3
...
Z-42-6
感谢您的帮助
答案 0 :(得分:2)
您应该将CROSS JOIN
与包含所有字母/数字的派生表一起使用
SELECT letters.let + '-' + numbers.num + '-' + numbers2.num
FROM(SELECT 'A' as let UNION ALL SELECT 'B' .....) letters
CROSS JOIN(SELECT '1' as num UNION ALL SELECT '2' ....) numbers -- up to 42
CROSS JOIN(SELECT '1' as num UNION ALL SELECT '2' ....) numbers2 -- up to 6
答案 1 :(得分:2)
这是一个使用CROSS JOIN
acrross 3值表
SELECT v1.val + '-' + CAST(v2.val AS VARCHAR(5)) + '-' + cast(v3.val AS VARCHAR(5))
FROM
(VALUES ('A'),('B'),('C'),('D')) v1(val)
CROSS JOIN
(VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15),(16)) v2(val)
CROSS JOIN
(VALUES (1),(2),(3),(4),(5),(6)) v3(val)
答案 2 :(得分:2)
Tally table可以省去逐个写入所有值的需要 如果您还没有计数表,请以最佳方式阅读this post。
SELECT Letter +'-'+ cast(fn as varchar(2)) +'-'+ cast(sn as char(1))
FROM (SELECT CHAR(Number) As Letter FROM Tally WHERE Number BETWEEN 65 AND 90) a
CROSS JOIN (SELECT Number as fn FROM Tally WHERE Number BETWEEN 1 AND 42) b
CROSS JOIN (SELECT Number as sn FROM Tally WHERE Number BETWEEN 1 AND 6) c
答案 3 :(得分:2)
只是为了好玩,一种数学方法:
with cte as
(
select 0 nr
union all
select nr+1 from cte where nr < 6551 --(26 * 42 * 6 = 6552 , 0 based = 6551)
)
select char(65 + (nr / 252)), 1 + ((nr / 6) % 42), 1 + nr % 6, * from cte -- Letter: divider = 6 * 42 = 252 , 65 = 'A'
option (maxrecursion 10000)
cte仅生成从0到6551的数字流(也可以使用other方法完成)。 之后,可以计算序列的每个片段。 但是对于记录,一旦创建序列,我最喜欢Zohar的解决方案:)
答案 4 :(得分:1)
还有一种方法:
;WITH cte AS (
SELECT 1 as digit
UNION ALL
SELECT digit + 1
FROM cte
WHERE digit < 90
)
SELECT CHAR(c1.digit) + '-' +
CAST(c2.digit as nvarchar(2)) + '-' +
CAST(c3.digit as nvarchar(2)) as seq
FROM cte c1
CROSS JOIN (SELECT digit FROM cte WHERE digit between 1 and 42) c2
CROSS JOIN (SELECT digit FROM cte WHERE digit between 1 and 6) c3
WHERE c1.digit between 65 and 90 --65..90 in ASCII is A..Z
输出:
seq
A-1-1
A-1-2
A-1-3
A-1-4
A-1-5
A-1-6
A-2-1
A-2-2
A-2-3
A-2-4
A-2-5
A-2-6
...
Z-42-3
Z-42-4
Z-42-5
Z-42-6