在SQL Server中将整数转换为二进制格式

时间:2016-04-07 14:26:36

标签: sql sql-server binary type-conversion sqldatatypes

我正在进行在线SQL练习并尝试将一系列整数转换为二进制数,而不是前导0.使用的数据库引擎是MS SQL Server。

以下是原始表格:

en_US

正确的输出应为:

...$ LC_NUMERIC=en_US.UTF-8 ./vrep

我尝试使用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

当我在MS SQL Server Management Studio中尝试此操作时,它返回了:

L

我无法弄清楚这是怎么发生的。请帮忙。

与此链接中提到的情况相反: SQL Server Convert integer to binary string

我不是要求可重复使用的解决方案,因为练习只允许一步解决方案...

由于问题提到所需的输出为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 "І ,我猜它是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 its binary number representation (without leading zeroes)

另外请忽略现在的领先0,因为它很容易摆脱它。

我应该更加清楚:在看到第一个答案后,我意识到这个问题实质上是要求在数字和字符串之间进行一系列转换,并使用公式在查询中获取二进制数。我不认为它要求二进制转换功能,但它要求"计算原始trip_no的二进制数,显示它,并减少前导0"。

2 个答案:

答案 0 :(得分:3)

这是一种不使用函数的奇特方式:

;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

答案 1 :(得分:2)

有点晚了,但这是使用按位AND的另一种方法。每个位的值计算为一个字符串,然后将所有位的值连接在一起。最后,将字符串强制转换为bigint以处置前导零。您可以将另一个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;

(阅读原帖上的所有评论,这与Zohar Peled提供的链接中的解决方案非常相似)