简体   繁体   English

将Varbinary(max)与另一个Varbinary(max)匹配

[英]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

----------------------------------------------------------
  • A Numbers table contains only one int field that contains 1 to 99999 value 一个Numbers表仅包含一个包含1到99999值的int字段
  • 96 use for a 15 Minute interval of one day (24* (60/15)) 96次使用,每15分钟间隔一天(24 *(60/15))

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM