[英]Match Varbinary(max) with another Varbinary(max)
i have a table with one binary column. 我有一个带有一个二进制列的表。 that contains 0x00010100000101010101......00 column datalength is 35040, i am prepare this data like
包含0x00010100000101010101 ...... 00列数据长度为35040,我正在准备此数据
@Jobbyte = COALESCE(@Jobbyte , 0x) + Cast ((Case When Sum(A.bit) >= 1 then 1 else 0 end)as binary(1))
i have to compare this binary data with another binary data and get the matching binary count. 我必须将此二进制数据与另一个二进制数据进行比较,并获得匹配的二进制计数。 both the binary data has equal length of data
两个二进制数据具有相等的数据长度
Please look below image, their is 2 binary data Binary1 and Binary2 i want to compare both binary data and get Sum of matching binary data. 请看下图,它们是2个二进制数据Binary1和Binary2,我想比较两个二进制数据并获取匹配的二进制数据的总和。 only one condition is when binary2's single bit is 0x01
只有一种情况是binary2的单个位为0x01
Last Row is indicate 0 = No Match, 1 = Match and last column is Sum of Last row (4) Please suggest me how can i compare , it's better if you can post a query 最后一行表示0 =不匹配,1 =匹配,最后一列是最后一行的总和(4)请建议我如何比较,如果可以发布查询会更好
Update 1 更新1
i am doing with 2 function and try to resolve but it's take to much time while execute with 10000 record, execution time for 1 record is 50 Millisecond 我正在使用2函数并尝试解决,但用10000条记录执行需要很多时间,一条记录的执行时间是50毫秒
Create FUNCTION [dbo].[Fn_BinaryToTable]
(
@BinaryData VARBINARY(max)
)
RETURNS TABLE
AS
RETURN
(
Select ((N.Number / 96) - (Case (N.Number % 96) when 0 Then 1 else 0 end))+1 As [FNNoDay],
(Case (N.Number % 96) when 0 then 96 else (N.Number % 96) end) * 15 AS [FnMinutes],
SUBSTRING(@BinaryData,(N.Number),1) AS [FNBIT]
from Numbers N
Where N.Number between 1 and (DATALENGTH(@BinaryData))
)
---------------------------------------------------------
Create FUNCTION [dbo].[fn_GetPercentage]
(
@JobValue int,
@CandidateBinary VARBINARY(max),
@JobBinary VARBINARY(max)
)
RETURNS Decimal
AS
BEGIN
DECLARE @RValue Decimal;
SELECT @RValue = SUM(cast(JB.FNBIT as int))
FROM dbo.Fn_BinaryToTable(@CandidateBinary) CB,
dbo.Fn_BinaryToTable(@JobBinary) JB
WHERE CB.FNNoDay = JB.FNNoDay
AND CB.FnMinutes = JB.FNMinutes
AND JB.FNBIT = CB.FNBIT
AND JB.FNBIT = 0x01
Return ((@RValue * 100)/ @JobValue);
END
--------------------------------------------------------
Declare @Jobbyte varbinary(max);
Declare @JobValue int;
Select @Jobbyte = JobBinary from Job;
Select @JobValue = count(*) from dbo.Fn_BinaryToTable(@Jobbyte) Where FNBIT = 0x01
----Select @JobValue = Sum(Cast(FNBIT as int)) from dbo.Fn_BinaryToTable(@Jobbyte)
set statistics time on
set statistics io on
select cid,dbo.fn_GetPercentage(@JobValue,cal,@Jobbyte) from eCal
set statistics time oFF
set statistics io oFF
----------------------------------------------------------
Please look at next code. 请看下一个代码。 It's generate rows and compare segments of both strings:
它生成行并比较两个字符串的段:
with q as (
SELECT
CONVERT(varchar(max), a ,2) a, -- convert 'a' bin data to varchar
CONVERT(varchar(max), b ,2) b -- convert 'b' bin data to varchar
FROM
(
SELECT -- a, b - test bin data
Cast (1 as binary(1)) + Cast (0 as binary(1)) + Cast (1 as binary(1)) a, -- 01 00 01
Cast (1 as binary(1)) + Cast (1 as binary(1)) + Cast (1 as binary(1)) b -- 01 01 01 - 2 matches
) k
)
select
--*, substring(a, x + 1, 2), substring(b, x + 1, 2)
sum(case when
substring(a, x + 1, 2) = substring(b, x + 1, 2) -- is block equals
then 1 else 0 end) sum_of_all_pair_equals
from
q
join
( -- generate 99999 rows for getting 2 chars block from staring a, b
select
x * 10000 + y * 1000 + z * 100 + k * 10 + l as x
from
(select 1 x union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) x,
(select 1 y union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) y,
(select 1 z union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) z,
(select 1 k union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) k,
(select 1 l union select 2 union select 3 union select 4 union select 5 union select 6 union select 7 union select 8 union select 9 union select 0) l
) x
on (
x between 0 and len(a) - 2 -- start from 1 to len - 2
and x % 2 = 0 -- get every even x
)
this query must be faster, but I have not tested it for perfomance: 此查询必须更快,但我尚未对其性能进行测试:
DECLARE @a VARCHAR(30); -- a bin string
DECLARE @b VARCHAR(30); -- b bin string
DECLARE @itersLeft INT; -- iterations count
DECLARE @i INT; -- counter
DECLARE @outCnt INT; -- result match counter
SELECT
@a = CONVERT(varchar(max), a ,2), -- convert 'a' bin data to varchar
@b = CONVERT(varchar(max), b ,2) -- convert 'b' bin data to varchar
FROM
(
SELECT -- a, b - test bin data
Cast (1 as binary(1)) + Cast (0 as binary(1)) + Cast (1 as binary(1)) a, -- 01 00 01
Cast (1 as binary(1)) + Cast (1 as binary(1)) + Cast (1 as binary(1)) b -- 01 01 01 - 2 matches
) k
;
SET @i = 0; -- init counter
SET @outCnt = 0; -- init result counter
SELECT @itersLeft = LEN(@a) - 2; -- setting max iterations counter
WHILE @i <= @itersLeft
BEGIN
if substring(@a, @i + 1, 2) = substring(@b, @i + 1, 2) -- compare data
SET @outCnt = @outCnt + 1; -- increase counter if equals
SET @i = @i + 2; -- increase counter by block size
END
SELECT @outCnt result; -- selecting result
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.