[ad_1]
Mengalami momen padat/senior hari ini…
Saya memiliki kueri SQL (yang diwarisi) yang dijalankan terhadap cte yang sekarang menghasilkan baris bernomor dari 1 hingga 16384. Saya mengharapkannya menghasilkan huruf kolom dalam rentang “A” hingga “XFC” (Sebelumnya menghasilkan “A” hingga “ZZ “)
Ini seharusnya berhasil
SELECT l, CASE WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END + CASE WHEN l >=27 then Char(65 + (l - 27) / 26 % 26) ELSE '' END + Char(65 + (l - 1) % 26) FROM eFinal WHERE l < 16384 ORDER BY l;
Faktanya, itu melakukan bekerja – SAMPAI kita sampai ke baris 6787 – alih-alih mengembalikan “JAA” melainkan kembali ke “IAA” (sampai ke “IAZ” dan dari sana melakukan beberapa hal aneh dan menakjubkan (termasuk karakter non-ascii))
Saya bisa menyiasatinya dengan
SELECT l, (CASE WHEN l >= 6787 THEN Char((65 + (l - 703) / 702 % 702) + 1) WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END) + (CASE WHEN l > 27 THEN (Char(65 + (l - 27) / 26 % 26)) ELSE '' END) +(Char(65 + (l - 1) % 26)) FROM eFinal WHERE l < 16384 ORDER BY l;
Yang berfungsi hingga “XFC”.
Yang saya tidak mengerti adalah…mengapa?
Saya kesulitan memahami pentingnya 6786 sebagai angka kunci – meskipun saya merasa berlebihan ketika menyadari bahwa itu adalah 26 x 255 tetapi l
apakah bigint jadi tidak relevan?
Apa yang saya coba:
Kode lengkap untuk mereproduksi perilaku
;with cte1 AS (select n from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1) ) AS X(n)) ,cte2 AS (SELECT a.n FROM cte1 a CROSS JOIN cte1 b) -- 10*10 ,cte3 AS (SELECT a.n FROM cte1 a CROSS JOIN cte2 b) -- 10*100 ,cte4 AS (SELECT a.n FROM cte2 a CROSS JOIN cte3 b ) -- 1000*100 ,eFinal AS (SELECT l = ROW_NUMBER() OVER (ORDER BY a.n) FROM cte2 a CROSS JOIN cte3 b ) SELECT l, CASE WHEN l >= 703 THEN Char(65 + (l - 703) / 702 % 702) ELSE '' END + CASE WHEN l >=27 then Char(65 + (l - 27) / 26 % 26) ELSE '' END + Char(65 + (l - 1) % 26) FROM eFinal --WHERE l < 16384 where l BETWEEN 6780 AND 6790 ORDER BY l;
Solusi 1
Karena perhitunganmu salah! 😀
DECLARE @cnt INT = 6785; WHILE @cnt < 6789 BEGIN SELECT @cnt , (@cnt - 27) / (26 * 26) , CASE WHEN (@cnt - 27 / (26 * 26)) > 0 THEN CHAR(65 + ((@cnt - 27) / (26 * 26))) ELSE '' END , Char(65 + (@cnt - 27) / 26 % 26) , Char(65 + (@cnt - 1) % 26) SET @cnt = @cnt + 1; END
[ad_2]
コメント