如何生成组合

时间:2016-06-28 10:04:06

标签: sql sql-server

我需要创建一个带有标识符列的表。标识符数据由3部分组成,第一部分是字母[A-Z],第二部分是数字[1-42],第三部分是数字[1-6]。

我想知道最快最好的方法,因为我真的被卡住了。输出应如下所示:

A-1-1
A-1-2
A-1-3
...
Z-42-6

感谢您的帮助

5 个答案:

答案 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