i have a table with one binary column. that contains 0x00010100000101010101......00 column datalength is 35040, i am prepare this data like
@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. only one condition is when binary2's single bit is 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
Update 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
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.