Apa cara tercepat untuk mengkonversi banyak int 1: 1 yang dapat dibatalkan menjadi string biner?

14

Bagian dari beban kerja saya menggunakan fungsi CLR yang mengimplementasikan algoritma hash seram untuk membandingkan baris untuk melihat apakah ada nilai kolom yang berubah. Fungsi CLR mengambil string biner sebagai input, jadi saya perlu cara cepat untuk mengubah baris menjadi string biner. Saya berharap untuk hash sekitar 10 miliar baris selama beban kerja penuh jadi saya ingin kode ini secepat mungkin.

Saya memiliki sekitar 300 tabel dengan skema berbeda. Untuk keperluan pertanyaan ini, silakan asumsikan struktur tabel sederhana dari 32 INTkolom yang dapat dibatalkan . Saya telah memberikan data sampel serta cara untuk membandingkan hasil di bagian bawah pertanyaan ini.

Baris harus dikonversi ke string biner yang sama jika semua nilai kolom sama. Baris harus dikonversi ke string biner yang berbeda jika ada nilai kolom yang berbeda. Misalnya, kode sesederhana yang berikut tidak akan berfungsi:

CAST(COL1 AS BINARY(4)) + CAST(COL2 AS BINARY(4)) + ..

Itu tidak menangani NULL dengan benar. Jika COL1NULL untuk baris 1 dan COL2NULL untuk baris 2 maka kedua baris akan dikonversi ke string NULL. Saya percaya bahwa penanganan NULL yang benar adalah bagian tersulit dalam mengubah seluruh baris dengan benar. Semua nilai yang diizinkan untuk kolom INT dimungkinkan.

Untuk mendahului beberapa pertanyaan:

  • Jika itu penting, sebagian besar waktu (90% +) kolom tidak akan NULL.
  • Saya harus menggunakan CLR.
  • Saya harus hash banyak baris ini. Saya tidak bisa menahan hash.
  • Saya percaya bahwa saya tidak dapat menggunakan mode batch untuk konversi karena keberadaan fungsi CLR.

Apa cara tercepat untuk mengonversi 32 INTkolom yang dapat dibatalkan menjadi BINARY(X)atau VARBINARY(X)string?

Sampel data dan kode seperti yang dijanjikan:

-- create sample data
DROP TABLE IF EXISTS dbo.TABLE_OF_32_INTS;

CREATE TABLE dbo.TABLE_OF_32_INTS (
    COL1 INT NULL,
    COL2 INT NULL,
    COL3 INT NULL,
    COL4 INT NULL,
    COL5 INT NULL,
    COL6 INT NULL,
    COL7 INT NULL,
    COL8 INT NULL,
    COL9 INT NULL,
    COL10 INT NULL,
    COL11 INT NULL,
    COL12 INT NULL,
    COL13 INT NULL,
    COL14 INT NULL,
    COL15 INT NULL,
    COL16 INT NULL,
    COL17 INT NULL,
    COL18 INT NULL,
    COL19 INT NULL,
    COL20 INT NULL,
    COL21 INT NULL,
    COL22 INT NULL,
    COL23 INT NULL,
    COL24 INT NULL,
    COL25 INT NULL,
    COL26 INT NULL,
    COL27 INT NULL,
    COL28 INT NULL,
    COL29 INT NULL,
    COL30 INT NULL,
    COL31 INT NULL,
    COL32 INT NULL
);

INSERT INTO dbo.TABLE_OF_32_INTS WITH (TABLOCK)
SELECT 0, 123, 12345, 1234567, 123456789
, 0, 123, 12345, 1234567, 123456789
, 0, 123, 12345, 1234567, 123456789
, 0, 123, 12345, 1234567, 123456789
, 0, 123, 12345, 1234567, 123456789
, 0, 123, 12345, 1234567, 123456789
, NULL, -876545321
FROM
(
    SELECT TOP (1000000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
    FROM master..spt_values t1
    CROSS JOIN master..spt_values t2
) q
OPTION (MAXDOP 1);


GO


-- procedure to test performance
CREATE OR ALTER PROCEDURE #p AS 
BEGIN

SET NOCOUNT ON;

DECLARE
@counter INT = 0,
@dummy VARBINARY(8000);

WHILE @counter < 10
BEGIN
    SELECT @dummy = -- this code is clearly incomplete as it does not handle NULLs
        CAST(COL1 AS BINARY(4)) + 
        CAST(COL2 AS BINARY(4)) + 
        CAST(COL3 AS BINARY(4)) + 
        CAST(COL4 AS BINARY(4)) + 
        CAST(COL5 AS BINARY(4)) + 
        CAST(COL6 AS BINARY(4)) + 
        CAST(COL7 AS BINARY(4)) + 
        CAST(COL8 AS BINARY(4)) + 
        CAST(COL9 AS BINARY(4)) + 
        CAST(COL10 AS BINARY(4)) + 
        CAST(COL11 AS BINARY(4)) + 
        CAST(COL12 AS BINARY(4)) + 
        CAST(COL13 AS BINARY(4)) + 
        CAST(COL14 AS BINARY(4)) + 
        CAST(COL15 AS BINARY(4)) + 
        CAST(COL16 AS BINARY(4)) + 
        CAST(COL17 AS BINARY(4)) + 
        CAST(COL18 AS BINARY(4)) + 
        CAST(COL19 AS BINARY(4)) + 
        CAST(COL20 AS BINARY(4)) + 
        CAST(COL21 AS BINARY(4)) + 
        CAST(COL22 AS BINARY(4)) + 
        CAST(COL23 AS BINARY(4)) + 
        CAST(COL24 AS BINARY(4)) + 
        CAST(COL25 AS BINARY(4)) + 
        CAST(COL26 AS BINARY(4)) + 
        CAST(COL27 AS BINARY(4)) + 
        CAST(COL28 AS BINARY(4)) + 
        CAST(COL29 AS BINARY(4)) + 
        CAST(COL30 AS BINARY(4)) + 
        CAST(COL31 AS BINARY(4)) + 
        CAST(COL32 AS BINARY(4))
    FROM dbo.TABLE_OF_32_INTS
    OPTION (MAXDOP 1);

    SET @counter = @counter + 1;
END;

SELECT cpu_time
FROM sys.dm_exec_requests
WHERE session_id = @@SPID;

END;

GO

-- run procedure
EXEC #p;

(Saya masih akan menggunakan hash seram pada hasil biner ini. Beban kerja menggunakan hash joins dan nilai hash digunakan untuk salah satu hash builds. Saya tidak ingin nilai biner panjang dalam hash build karena membutuhkan terlalu banyak Penyimpanan.)

Joe Obbish
sumber

Jawaban:

6

Bagaimana dengan menggunakan BINARY(5)dan mengonversi NULLs ke sesuatu di luar kisaran untuk INT:

SELECT @dummy =
    ISNULL(CAST(COL1  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL2  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL3  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL4  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL5  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL6  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL7  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL8  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL9  AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL10 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL11 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL12 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL13 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL14 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL15 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL16 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL17 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL18 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL19 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL20 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL21 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL22 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL23 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL24 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL25 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL26 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL27 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL28 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL29 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL30 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL31 AS BINARY(5)), 0x0100000000) + 
    ISNULL(CAST(COL32 AS BINARY(5)), 0x0100000000)
FROM dbo.TABLE_OF_32_INTS
OPTION (MAXDOP 1);
Steven Hibble
sumber
11

Di komputer saya (SQL Server 2017), fungsi C # SQLCLR berikut berjalan sekitar 30% lebih cepat dari binary(5)ide, 35% lebih cepat daripada CONCAT_WS, dan setengah waktu dari jawaban otomatis.

Itu membutuhkan UNSAFEizin dan menggunakan pointer. Implementasinya sangat spesifik terkait dengan data uji.

Untuk tujuan pengujian, cara termudah untuk membuat perakitan yang tidak aman ini bekerja adalah dengan mengatur basis data ke TRUSTWORTHYdan menonaktifkan opsi konfigurasi keamanan CLR yang ketat jika perlu.

Kode yang dikompilasi

Untuk kenyamanan, CREATE ASSEMBLYbit yang dikompilasi ada di https://gist.github.com/SQLKiwi/72d01b661c74485900e7ebcfdc63ab8e

T-SQL Function Stub

CREATE FUNCTION dbo.NullableIntsToBinary
(
    @Col01 int, @Col02 int, @Col03 int, @Col04 int, @Col05 int, @Col06 int, @Col07 int, @Col08 int, 
    @Col09 int, @Col10 int, @Col11 int, @Col12 int, @Col13 int, @Col14 int, @Col15 int, @Col16 int, 
    @Col17 int, @Col18 int, @Col19 int, @Col20 int, @Col21 int, @Col22 int, @Col23 int, @Col24 int, 
    @Col25 int, @Col26 int, @Col27 int, @Col28 int, @Col29 int, @Col30 int, @Col31 int, @Col32 int
)
RETURNS binary(132) 
WITH EXECUTE AS CALLER
AS EXTERNAL NAME Obbish.UserDefinedFunctions.NullableIntsToBinary;

Kode sumber

Sumber C # ada di https://gist.github.com/SQLKiwi/64f320fe7fd802a68a3a644aa8b8af9f

Jika Anda mengkompilasi ini untuk diri sendiri, Anda harus menggunakan Perpustakaan Kelas (.dll) sebagai jenis proyek target dan periksa opsi perbolehkan kode tidak aman .

Solusi gabungan

Karena Anda akhirnya ingin menghitung SpookyHash dari data biner yang dikembalikan di atas, Anda dapat memanggil SpookyHash dalam fungsi CLR dan mengembalikan hash 16-byte.

Contoh implementasi berdasarkan tabel dengan campuran tipe data kolom ada di https://gist.github.com/SQLKiwi/6f82582a4ad1920c372fac118ec82460 . Ini termasuk versi inline yang tidak aman dari algoritme Spooky Hash yang berasal dari Jon Hanna's SpookilySharp dan kode sumber domain C asli publik oleh Bob Jenkins.

Paul White 9
sumber
7

Sebuah INTkolom memiliki empat byte nilai yang diperbolehkan yang sama persis dengan ukuran BINARY(4). Dengan kata lain, setiap nilai yang mungkin dari BINARY (4) dicocokkan dengan nilai INTkolom yang mungkin. Jadi kecuali ada nilai yang tidak diizinkan di INTkolom, tidak ada pengganti yang aman untuk NULL. Apakah NULL kolom atau tidak harus dikodekan secara terpisah. Itu tidak bisa masuk dalam BINARY(4).

Salah satu cara untuk melakukan ini adalah dengan bitmap NULL. Pertimbangkan kode berikut:

CAST(       
    CASE WHEN COL1 IS NOT NULL THEN 0 ELSE 1 END | 
    CASE WHEN COL2 IS NOT NULL THEN 0 ELSE 2 END | 
    CASE WHEN COL3 IS NOT NULL THEN 0 ELSE 4 END | 
    CASE WHEN COL4 IS NOT NULL THEN 0 ELSE 8 END | 
    CASE WHEN COL5 IS NOT NULL THEN 0 ELSE 16 END | 
    CASE WHEN COL6 IS NOT NULL THEN 0 ELSE 32 END | 
    CASE WHEN COL7 IS NOT NULL THEN 0 ELSE 64 END | 
    CASE WHEN COL8 IS NOT NULL THEN 0 ELSE 128 END
AS BINARY(1))

Apakah delapan kolom NULL cocok dalam satu byte. Ekspresi ini dapat dibandingkan antara baris untuk memeriksa bahwa semua kolom yang sama adalah NULL atau bukan NULL. Dengan informasi tambahan itu maka menjadi aman untuk mengganti nilai kolom NULL dengan apa pun yang bukan NULL. Saya menemukan CAST(ISNULL(COL1, 0) AS BINARY(4))yang tercepat, meskipun variasi lain seperti ISNULL(CAST(COL1 AS VARBINARY(4)), 0x)itu mungkin.

Sulit untuk membuktikan sesuatu dengan pasti, tetapi saya menemukan detail berikut sebagai yang tercepat:

  • Menggunakan 0 untuk NOT NULL dalam bitmap karena saya tahu sebagian besar nilai kolom tidak akan NULL
  • Menggunakan bitwise atau bukannya penambahan untuk bitmap
  • Memeriksa apakah nilai kolom NULL yang bertentangan dengan nilai biner yang dikonversi

Di mesin saya benchmark membutuhkan waktu sekitar 27,5 CPU detik. Sayangnya, langkah bitmap NULL membutuhkan sekitar sepertiga dari waktu itu. Alangkah baiknya jika ada cara yang lebih cepat untuk melakukan ini.

Inilah solusi lengkapnya:

SELECT
    CAST(ISNULL(COL1, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL2, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL3, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL4, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL5, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL6, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL7, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL8, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL9, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL10, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL11, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL12, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL13, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL14, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL15, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL16, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL17, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL18, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL19, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL20, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL21, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL22, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL23, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL24, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL25, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL26, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL27, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL28, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL29, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL30, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL31, 0) AS BINARY(4)) + 
    CAST(ISNULL(COL32, 0) AS BINARY(4)) + 
    CAST(       
        CASE WHEN COL1 IS NOT NULL THEN 0 ELSE 1 END | 
        CASE WHEN COL2 IS NOT NULL THEN 0 ELSE 2 END | 
        CASE WHEN COL3 IS NOT NULL THEN 0 ELSE 4 END | 
        CASE WHEN COL4 IS NOT NULL THEN 0 ELSE 8 END | 
        CASE WHEN COL5 IS NOT NULL THEN 0 ELSE 16 END | 
        CASE WHEN COL6 IS NOT NULL THEN 0 ELSE 32 END | 
        CASE WHEN COL7 IS NOT NULL THEN 0 ELSE 64 END | 
        CASE WHEN COL8 IS NOT NULL THEN 0 ELSE 128 END
    AS BINARY(1)) + 
    CAST(   
        CASE WHEN COL9  IS NOT NULL THEN 0 ELSE 1 END | 
        CASE WHEN COL10 IS NOT NULL THEN 0 ELSE 2 END | 
        CASE WHEN COL11 IS NOT NULL THEN 0 ELSE 4 END | 
        CASE WHEN COL12 IS NOT NULL THEN 0 ELSE 8 END | 
        CASE WHEN COL13 IS NOT NULL THEN 0 ELSE 16 END | 
        CASE WHEN COL14 IS NOT NULL THEN 0 ELSE 32 END | 
        CASE WHEN COL15 IS NOT NULL THEN 0 ELSE 64 END | 
        CASE WHEN COL16 IS NOT NULL THEN 0 ELSE 128 END
    AS BINARY(1)) + 
    CAST(   
        CASE WHEN COL17 IS NOT NULL THEN 0 ELSE 1 END | 
        CASE WHEN COL18 IS NOT NULL THEN 0 ELSE 2 END | 
        CASE WHEN COL19 IS NOT NULL THEN 0 ELSE 4 END | 
        CASE WHEN COL20 IS NOT NULL THEN 0 ELSE 8 END | 
        CASE WHEN COL21 IS NOT NULL THEN 0 ELSE 16 END | 
        CASE WHEN COL22 IS NOT NULL THEN 0 ELSE 32 END | 
        CASE WHEN COL23 IS NOT NULL THEN 0 ELSE 64 END | 
        CASE WHEN COL24 IS NOT NULL THEN 0 ELSE 128 END
    AS BINARY(1)) + 
    CAST(   
        CASE WHEN COL25 IS NOT NULL THEN 0 ELSE 1 END | 
        CASE WHEN COL26 IS NOT NULL THEN 0 ELSE 2 END | 
        CASE WHEN COL27 IS NOT NULL THEN 0 ELSE 4 END | 
        CASE WHEN COL28 IS NOT NULL THEN 0 ELSE 8 END | 
        CASE WHEN COL29 IS NOT NULL THEN 0 ELSE 16 END | 
        CASE WHEN COL30 IS NOT NULL THEN 0 ELSE 32 END | 
        CASE WHEN COL31 IS NOT NULL THEN 0 ELSE 64 END | 
        CASE WHEN COL32 IS NOT NULL THEN 0 ELSE 128 END
    AS BINARY(1))
FROM dbo.TABLE_OF_32_INTS
OPTION (MAXDOP 1);
Joe Obbish
sumber
5

Dalam pengujian saya, concat_ws sedikit lebih cepat (18 detik) daripada solusi nol bitmap Anda (26 detik). Akan ada lebih banyak data untuk diacak sehingga Anda mungkin melihat beberapa penurunan kinerja di tempat lain dan jika Anda ingin mencampurnya dengan kolom karakter Anda harus memilih pembatas dengan bijak.

select @dummy = cast(concat_ws('|',
         isnull(cast(T.COL1  as varchar(11)), ''),
         isnull(cast(T.COL2  as varchar(11)), ''),
         isnull(cast(T.COL3  as varchar(11)), ''),
         isnull(cast(T.COL4  as varchar(11)), ''),
         isnull(cast(T.COL5  as varchar(11)), ''),
         isnull(cast(T.COL6  as varchar(11)), ''),
         isnull(cast(T.COL7  as varchar(11)), ''),
         isnull(cast(T.COL8  as varchar(11)), ''),
         isnull(cast(T.COL9  as varchar(11)), ''),
         isnull(cast(T.COL10 as varchar(11)), ''),
         isnull(cast(T.COL11 as varchar(11)), ''),
         isnull(cast(T.COL12 as varchar(11)), ''),
         isnull(cast(T.COL13 as varchar(11)), ''),
         isnull(cast(T.COL14 as varchar(11)), ''),
         isnull(cast(T.COL15 as varchar(11)), ''),
         isnull(cast(T.COL16 as varchar(11)), ''),
         isnull(cast(T.COL17 as varchar(11)), ''),
         isnull(cast(T.COL18 as varchar(11)), ''),
         isnull(cast(T.COL19 as varchar(11)), ''),
         isnull(cast(T.COL20 as varchar(11)), ''),
         isnull(cast(T.COL21 as varchar(11)), ''),
         isnull(cast(T.COL22 as varchar(11)), ''),
         isnull(cast(T.COL23 as varchar(11)), ''),
         isnull(cast(T.COL24 as varchar(11)), ''),
         isnull(cast(T.COL25 as varchar(11)), ''),
         isnull(cast(T.COL26 as varchar(11)), ''),
         isnull(cast(T.COL27 as varchar(11)), ''),
         isnull(cast(T.COL28 as varchar(11)), ''),
         isnull(cast(T.COL29 as varchar(11)), ''),
         isnull(cast(T.COL30 as varchar(11)), ''),
         isnull(cast(T.COL31 as varchar(11)), ''),
         isnull(cast(T.COL32 as varchar(11)), ''))
       as varbinary(8000))
from dbo.TABLE_OF_32_INTS as T
option (maxdop 1)
Mikael Eriksson
sumber
2
Terima kasih untuk ini. Ini lebih cepat untuk saya juga, tetapi memiliki kelemahan karena menghasilkan string biner yang lebih panjang (191 karakter vs 132 untuk data sampel). Kami pasti akan mempertimbangkannya.
Joe Obbish
-1

Jika Anda dapat memastikan sebelumnya bahwa Anda tidak menyimpan int tertentu, -2,147,483,648maka Anda dapat melakukan sesuatu seperti:

 SELECT @dummy = 
        coalesce(CAST(COL1 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL2 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL3 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL4 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL5 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL6 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL7 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL8 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL9 AS BINARY(4)),  0x80000000) + 
        coalesce(CAST(COL10 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL11 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL12 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL13 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL14 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL15 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL16 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL17 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL18 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL19 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL20 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL21 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL22 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL23 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL24 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL25 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL26 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL27 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL28 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL29 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL30 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL31 AS BINARY(4)), 0x80000000) + 
        coalesce(CAST(COL32 AS BINARY(4)), 0x80000000) 
    FROM dbo.TABLE_OF_32_INTS
David Browne - Microsoft
sumber
Terima kasih atas jawabannya. Semua nilai yang diizinkan untuk kolom INT dimungkinkan.
Joe Obbish