MariaDB講座 / ROUND・CASTで数値を丸め、型を変換する

ROUNDは指定した桁で数値を丸め、CASTは明示した型へ値を変換します。金額ではDECIMALなどの正確な表現と丸める時点を決め、結果だけでなく元の入力や変換警告も確認します。

計算・丸め・表示を別の処理にする

10%割引、少数2桁への丸め、桁区切りを付けた表示は別の処理です。計算中は数値を保ち、通貨記号や区切りを付けた文字列を再び数値として合計しないようにします。行ごとに丸めるか、合計後に丸めるかで結果が変わる場合もあります。

近似と正確な数は数値型、条件で計算式を選ぶ場合はCASEと組み合わせます。CASTを明示しても、入力が業務規則に適合した証明にはなりません。

正確な数で割引を計算する

course_userでshopcourseへ接続し、SELECT VERSION(), DATABASE();とSHOW TABLES;で環境と同名表を確認します。通常例をUTF-8ファイルに保存してSOURCEで実行できます。既存の同名表は用途・定義・行を調べ、不要と確認できるまでは置き換えません。

USE shopcourse;
CREATE TABLE products_20_lab (
  product_id INT NOT NULL AUTO_INCREMENT,
  product_name VARCHAR(100) NOT NULL,
  category VARCHAR(30) NOT NULL,
  price DECIMAL(10,2) NOT NULL,
  stock INT NOT NULL DEFAULT 0,
  note VARCHAR(100) NULL DEFAULT NULL,
  PRIMARY KEY (product_id),
  CONSTRAINT ck_p20_price CHECK (price >= 0),
  CONSTRAINT ck_p20_stock CHECK (stock >= 0)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO products_20_lab (product_id,product_name,category,price,stock,note) VALUES (1, '노트', '문구', 3500.00, 20, NULL),
  (2, '볼펜', '문구', 1500.00, 0, ''),
  (3, '머그컵', '생활', 8000.00, 12, '선물 포장'),
  (4, '스탠드', '생활', 25000.00, 5, NULL),
  (5, '파일', '문구', 1500.00, 50, ''),
  (6, '케이블', '전자', 8000.00, 0, '호환 확인');

SQL内の韓国語サンプルは文字コードと結果を原文にそろえたものです。ID1~6はノート、ペン、マグカップ、ライト、ファイル、ケーブル、分類は文具・生活用品・電子用品です。数値とIDで結果を比較します。noteは1・4がNULL、2・5が空文字、他は記入済みで、在庫は20・0・12・5・50・0です。

SELECT product_id, price, ROUND(price * 0.9,2) AS discounted_price
FROM products_20_lab ORDER BY product_id;

ノートは3150.00、ペンは1350.00、ライトは22500.00になります。priceはDECIMAL、0.9は正確な十進リテラルです。文法を学ぶ例であり、税や実販売の規則は別に決めます。

中間値と負の桁を確認する

DECIMALを明示した境界の比較です。

SELECT ROUND(CAST('1.235' AS DECIMAL(10,3)),2),
 ROUND(CAST('-1.235' AS DECIMAL(10,3)),2);
SELECT ROUND(12345,-2);

1.235は1.24、−1.235は−1.24、12345を−2桁で丸めると12300です。DOUBLEを含む式や指数表記などの近似入力は、同じ中間値の規則になると決めつけません。税や請求の仕様に従い、小数の境界を含めて比較します。

型変換で失う情報を把握する

次を実行します。

SELECT CAST('12.90' AS DECIMAL(10,2)),
 CAST('0012' AS UNSIGNED), CAST(123 AS CHAR);

結果は12.90、12、文字列123です。DECIMAL(10,2)は全体10桁で小数2桁、0012を整数へ変えると先頭0は失われます。商品コードや郵便番号を量として扱わないでください。小数部の削減、範囲外、負数からUNSIGNEDへの変換は別々の条件として確認します。

不正な数値文字列の警告を読む

変換の直後に診断を読みます。

SELECT CAST('12abc' AS DECIMAL(10,2));
SHOW WARNINGS;

このSELECTは12abcの数値部分を12.00へ変換し、切り詰め警告を返す場合があります。数値が返っても入力全体が正しい証拠にはなりません。保存文かSELECTか、SQLモード、保存先の型で警告とエラーの扱いが変わるため、受け入れる書式と範囲を入力側でも検証します。

主キー、元の価格、中間計算と最終値を並べて調べます。NULLの原因を調べず0で隠さず、保存価格へUPDATEする前にSELECTで範囲と計算を確認します。

再実習では選択中のDB、定義、保存行を確認し、必要なものを保存した後、削除可能なこの記事の実習表だけを削除します。DROP TABLEは定義と行を消し、通常のROLLBACKでは戻せません。他の記事や実アプリケーションの表へ範囲を広げないでください。

DROP TABLE shopcourse.products_20_lab;

関連する公式リファレンス