簡體   English   中英

MSSQL BIT_COUNT(漢明距離)

[英]MSSQL BIT_COUNT (Hammingdistance)

MSSQL中是否有類似於MYSQL BIT_COUNT的function? 我想在 MSSQL 中創建一個非常簡單的 Hammingdistance function,我可以在我的選擇中使用它。

這是我為 MYSQL 准備的:

CREATE FUNCTION `HAMMINGDISTANCE`(`hasha` BIGINT, `hashb` BIGINT)
    RETURNS int(11)
    DETERMINISTIC
    RETURN 
    BIT_COUNT(hasha^hashb)

為什么不在T-SQL中編寫自己的bit_count代碼? 如果您只需要計算bigint中的設置位數,則無需使用SQL CLR。 這是一個例子:

CREATE FUNCTION bit_count
(
   @pX bigint
)
RETURNS int
AS
BEGIN
   DECLARE @lRet integer
   SET @lRet = 0
   WHILE (@pX != 0)
   BEGIN
      SET @lRet = @lRet + (@pX & 1)
      SET @pX = @pX / 2
   END   
   return @lRet   
END
GO

此外,這是一個小提琴你可以嘗試看到這個功能在行動。

請注意,此算法僅適用於非負bigints。 如果您正在尋找適用於負bigint的算法,請參閱此鏈接

我剛剛使用dcp提供的代碼寫了一個HAMMINGDISTANCE,它似乎工作。

CREATE FUNCTION [dbo].[HAMMINGDISTANCE](@hasha BIGINT, @hashb BIGINT)
    RETURNS int
AS
BEGIN
   DECLARE @pX BIGINT
   DECLARE @lRet integer
   SET @lRet = 0
   SET @pX = @hasha ^ @hashb
   WHILE (@pX != 0)
   BEGIN
      SET @lRet = @lRet + (@pX & 1)
      SET @pX = @pX / 2
   END   
   return @lRet   
END

GO
CREATE FUNCTION [dbo].[fn_hamming_distance]
(
    @a     BIGINT,
    @b     BIGINT
)
RETURNS TINYINT
AS
BEGIN
    DECLARE @c BIGINT = @a ^ @b
    RETURN 
    CASE 
         WHEN @c IS NULL
              THEN NULL
         ELSE CASE 
                   WHEN @c < 0 THEN 1
                   ELSE 0
              END
              +
              CASE 
                   WHEN @c & 0x4000000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2000000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1000000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x800000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x400000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x200000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x100000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x80000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x40000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x20000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x10000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x8000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x4000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1000000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x800000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x400000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x200000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x100000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x80000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x40000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x20000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x10000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x8000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x4000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1000000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x800000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x400000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x200000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x100000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x80000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x40000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x20000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x10000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x8000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x4000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1000000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x800000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x400000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x200000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x100000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x80000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x40000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x20000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x10000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x8000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x4000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1000 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x800 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x400 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x200 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x100 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x80 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x40 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x20 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x10 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x8 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x4 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x2 > 0 THEN 1
               ELSE 0
          END
          +
          CASE 
               WHEN @c & 0x1 > 0 THEN 1
               ELSE 0
          END
    END
END

MSSQL中是否有類似於MYSQL BIT_COUNT function的function?

是的,有BIT_COUNT

問題是它僅可從 SQL Server 2022 獲得,因此當您提出問題時不可用,但最終會對未來的訪問者有用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM