在 SQL 服务器中将整数转换为二进制格式
Convert integer into binary format in SQL Server
我正在做一个在线 SQL 练习,试图将一系列整数转换为不带前导 0 的二进制数。使用的数据库引擎是 MS SQL Server。
以下为原文表格:
trip_no
1100
1101
1123
1124
1145
1146
1181
1182
1187
1188
1195
1196
7771
7772
7773
7774
7775
7776
7777
7778
8881
8882
正确的输出应该是这样的:
trip_no trip_no_bi
1100 10001001100
1101 10001001101
1123 10001100011
1124 10001100100
1145 10001111001
1146 10001111010
1181 10010011101
1182 10010011110
1187 10010100011
1188 10010100100
1195 10010101011
1196 10010101100
7771 1111001011011
7772 1111001011100
7773 1111001011101
7774 1111001011110
7775 1111001011111
7776 1111001100000
7777 1111001100001
7778 1111001100010
8881 10001010110001
8882 10001010110010
我尝试使用 cast((trip_no) as varbinary)
语法,但结果很奇怪。比如我在练习网页上用cast()
函数转换1100
返回L
,剩下的输出是这样的:
trip_no
1100 L
1101 M
1123 c
1124 d
1145 y
1146 z
1181 ќ
1182 ћ
1187 Ј
1188 ¤
1195 «
1196 ¬
7771 [
7772 \
7773 ]
7774 ^
7775 _
7776 `
7777 a
7778 b
8881 "±
8882 "І
而当我在 MS SQL Server Management Studio 中尝试此操作时,它返回:
trip_no trip_no_bi
1100 0x0000044C
1101 0x0000044D
1123 0x00000463
1124 0x00000464
1145 0x00000479
1146 0x0000047A
1181 0x0000049D
1182 0x0000049E
1187 0x000004A3
1188 0x000004A4
1195 0x000004AB
1196 0x000004AC
7771 0x00001E5B
7772 0x00001E5C
7773 0x00001E5D
7774 0x00001E5E
7775 0x00001E5F
7776 0x00001E60
7777 0x00001E61
7778 0x00001E62
8881 0x000022B1
8882 0x000022B2
我不明白这是怎么发生的。请帮忙。
与link中询问的情况相反:
SQL Server Convert integer to binary string
我不要求可重复使用的解决方案,因为练习只允许一步解决...
由于问题提到期望的输出是 its binary number representation (without leading zeroes)
,我猜它是 INT
或 VARCHAR
。
另外请忽略前面的 0,因为它很容易去掉。
这一点我应该更清楚了:看到第一个答案后我意识到这道题本质上是要求一系列数字和字符串之间的转换,用公式在查询中得到二进制数。我不认为它要求二进制转换功能,但它要求 "Calculate the binary number of the original trip_no, present it, and trim down the leading 0".
这是一种不使用函数的奇特方法:
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N, N a)
SELECT yourtable.num, x.bin
FROM (values(0),(1),(2),(3),(4),(9),(20),(100),(1001)) yourtable(num)
CROSS APPLY(
SELECT
REVERSE((
SELECT cast(num / power(2, N - 1) % 2 as char(1))
FROM tally t1
WHERE num >= power(2, N - 1)
for xml path(''), type
).value('.', 'varchar(max)')) [bin]
) x
结果:
num bin
0 NULL
1 1
2 10
3 11
4 100
9 1001
20 10100
100 1100100
1001 1111101001
有点晚了,但这是另一种使用按位与的方法。每个位的值被计算为一个字符串,然后将所有位的值连接在一起。最后,字符串被强制转换为 bigint
以处理前导零。您可以包装 this is another CAST
以将输出转换为字符串。
DECLARE @t TABLE (trip_no int);
INSERT @t (trip_no)
VALUES (1100),(1101),(1123),(1124),(1145),(1146),(1181),(1182),
(1187),(1188),(1195),(1196),(7771),(7772),(7773),(7774),(7775),
(7776),(7777),(7778),(8881),(8882);
SELECT trip_no
,CAST(CASE trip_no & 32768 WHEN 32768 THEN '1' ELSE '0' END
+CASE trip_no & 16384 WHEN 16384 THEN '1' ELSE '0' END
+CASE trip_no & 8192 WHEN 8192 THEN '1' ELSE '0' END
+CASE trip_no & 4096 WHEN 4096 THEN '1' ELSE '0' END
+CASE trip_no & 2048 WHEN 2048 THEN '1' ELSE '0' END
+CASE trip_no & 1024 WHEN 1024 THEN '1' ELSE '0' END
+CASE trip_no & 512 WHEN 512 THEN '1' ELSE '0' END
+CASE trip_no & 256 WHEN 256 THEN '1' ELSE '0' END
+CASE trip_no & 128 WHEN 128 THEN '1' ELSE '0' END
+CASE trip_no & 64 WHEN 64 THEN '1' ELSE '0' END
+CASE trip_no & 32 WHEN 32 THEN '1' ELSE '0' END
+CASE trip_no & 16 WHEN 16 THEN '1' ELSE '0' END
+CASE trip_no & 8 WHEN 8 THEN '1' ELSE '0' END
+CASE trip_no & 4 WHEN 4 THEN '1' ELSE '0' END
+CASE trip_no & 2 WHEN 2 THEN '1' ELSE '0' END
+CASE trip_no & 1 WHEN 1 THEN '1' ELSE '0' END AS bigint) AS bin_value
FROM @t;
(阅读原文post的所有评论,这与Zohar Peled提供的link中的解决方案非常相似)
我正在做一个在线 SQL 练习,试图将一系列整数转换为不带前导 0 的二进制数。使用的数据库引擎是 MS SQL Server。
以下为原文表格:
trip_no
1100
1101
1123
1124
1145
1146
1181
1182
1187
1188
1195
1196
7771
7772
7773
7774
7775
7776
7777
7778
8881
8882
正确的输出应该是这样的:
trip_no trip_no_bi
1100 10001001100
1101 10001001101
1123 10001100011
1124 10001100100
1145 10001111001
1146 10001111010
1181 10010011101
1182 10010011110
1187 10010100011
1188 10010100100
1195 10010101011
1196 10010101100
7771 1111001011011
7772 1111001011100
7773 1111001011101
7774 1111001011110
7775 1111001011111
7776 1111001100000
7777 1111001100001
7778 1111001100010
8881 10001010110001
8882 10001010110010
我尝试使用 cast((trip_no) as varbinary)
语法,但结果很奇怪。比如我在练习网页上用cast()
函数转换1100
返回L
,剩下的输出是这样的:
trip_no
1100 L
1101 M
1123 c
1124 d
1145 y
1146 z
1181 ќ
1182 ћ
1187 Ј
1188 ¤
1195 «
1196 ¬
7771 [
7772 \
7773 ]
7774 ^
7775 _
7776 `
7777 a
7778 b
8881 "±
8882 "І
而当我在 MS SQL Server Management Studio 中尝试此操作时,它返回:
trip_no trip_no_bi
1100 0x0000044C
1101 0x0000044D
1123 0x00000463
1124 0x00000464
1145 0x00000479
1146 0x0000047A
1181 0x0000049D
1182 0x0000049E
1187 0x000004A3
1188 0x000004A4
1195 0x000004AB
1196 0x000004AC
7771 0x00001E5B
7772 0x00001E5C
7773 0x00001E5D
7774 0x00001E5E
7775 0x00001E5F
7776 0x00001E60
7777 0x00001E61
7778 0x00001E62
8881 0x000022B1
8882 0x000022B2
我不明白这是怎么发生的。请帮忙。
与link中询问的情况相反: SQL Server Convert integer to binary string
我不要求可重复使用的解决方案,因为练习只允许一步解决...
由于问题提到期望的输出是 its binary number representation (without leading zeroes)
,我猜它是 INT
或 VARCHAR
。
另外请忽略前面的 0,因为它很容易去掉。
这一点我应该更清楚了:看到第一个答案后我意识到这道题本质上是要求一系列数字和字符串之间的转换,用公式在查询中得到二进制数。我不认为它要求二进制转换功能,但它要求 "Calculate the binary number of the original trip_no, present it, and trim down the leading 0".
这是一种不使用函数的奇特方法:
;WITH N(N)AS
(SELECT 1 FROM(VALUES(1),(1),(1),(1),(1))M(N)),
tally(N)AS(SELECT ROW_NUMBER()OVER(ORDER BY N.N)FROM N, N a)
SELECT yourtable.num, x.bin
FROM (values(0),(1),(2),(3),(4),(9),(20),(100),(1001)) yourtable(num)
CROSS APPLY(
SELECT
REVERSE((
SELECT cast(num / power(2, N - 1) % 2 as char(1))
FROM tally t1
WHERE num >= power(2, N - 1)
for xml path(''), type
).value('.', 'varchar(max)')) [bin]
) x
结果:
num bin
0 NULL
1 1
2 10
3 11
4 100
9 1001
20 10100
100 1100100
1001 1111101001
有点晚了,但这是另一种使用按位与的方法。每个位的值被计算为一个字符串,然后将所有位的值连接在一起。最后,字符串被强制转换为 bigint
以处理前导零。您可以包装 this is another CAST
以将输出转换为字符串。
DECLARE @t TABLE (trip_no int);
INSERT @t (trip_no)
VALUES (1100),(1101),(1123),(1124),(1145),(1146),(1181),(1182),
(1187),(1188),(1195),(1196),(7771),(7772),(7773),(7774),(7775),
(7776),(7777),(7778),(8881),(8882);
SELECT trip_no
,CAST(CASE trip_no & 32768 WHEN 32768 THEN '1' ELSE '0' END
+CASE trip_no & 16384 WHEN 16384 THEN '1' ELSE '0' END
+CASE trip_no & 8192 WHEN 8192 THEN '1' ELSE '0' END
+CASE trip_no & 4096 WHEN 4096 THEN '1' ELSE '0' END
+CASE trip_no & 2048 WHEN 2048 THEN '1' ELSE '0' END
+CASE trip_no & 1024 WHEN 1024 THEN '1' ELSE '0' END
+CASE trip_no & 512 WHEN 512 THEN '1' ELSE '0' END
+CASE trip_no & 256 WHEN 256 THEN '1' ELSE '0' END
+CASE trip_no & 128 WHEN 128 THEN '1' ELSE '0' END
+CASE trip_no & 64 WHEN 64 THEN '1' ELSE '0' END
+CASE trip_no & 32 WHEN 32 THEN '1' ELSE '0' END
+CASE trip_no & 16 WHEN 16 THEN '1' ELSE '0' END
+CASE trip_no & 8 WHEN 8 THEN '1' ELSE '0' END
+CASE trip_no & 4 WHEN 4 THEN '1' ELSE '0' END
+CASE trip_no & 2 WHEN 2 THEN '1' ELSE '0' END
+CASE trip_no & 1 WHEN 1 THEN '1' ELSE '0' END AS bigint) AS bin_value
FROM @t;
(阅读原文post的所有评论,这与Zohar Peled提供的link中的解决方案非常相似)