powとfloorで実装
-- v: 数値列, s: スケール列(例: 2 なら小数2桁、-1 なら10の位)
SELECT
sign(v) * floor(abs(v) * pow(10, s) + 0.5) / pow(10, s) AS v_rounded
FROM t;
よく使うscaleはリテラルでroundを使用する(高速化)
SELECT
CASE s
WHEN 0 THEN round(v, 0)
WHEN 1 THEN round(v, 1)
WHEN 2 THEN round(v, 2)
WHEN -1 THEN round(v, -1)
ELSE /* フォールバック */ sign(v) * floor(abs(v) * pow(10, s) + 0.5) / pow(10, s)
END AS v_rounded
FROM t;
メモ・注意点
- pow(10, s) は s が大きいと浮動小数誤差が出ます。必要スケールが 0〜6 桁程度なら実務上十分。より厳密にしたい場合は固定スケールの DECIMAL にキャストして使うか、CASE で小さな範囲に限定してください。
- 結果を DECIMAL にしたい場合は 固定スケールに CAST します(可変スケールの DECIMAL 型は定義できません)。