この記事では、SQLでABS関数を使って絶対値を取得する方法を詳しく解説します。
基本的な使い方から応用的な活用法まで、具体的な例を使って分かりやすく説明していきます。
ABS関数とは
ABS関数は、数値の絶対値を返すSQL標準関数です。
絶対値とは、数値の符号(プラス・マイナス)を無視した値のことで、0からの距離を表します。
絶対値の基本概念
絶対値の定義
- 正の数:そのままの値(例:5の絶対値は5)
- 負の数:符号を取った値(例:-5の絶対値は5)
- ゼロ:0のまま(0の絶対値は0)
ビジネスでの活用場面
- 売上の増減額を統一的に比較
- 在庫の過不足を絶対値で管理
- 予算と実績の差異分析
- 距離や誤差の計算
基本的な構文と使い方

基本構文
ABS(数値または数値列)
パラメータ
- 数値:絶対値を求めたい数値
- 数値列:テーブルの数値カラム
- 計算式:数値を返す計算式
戻り値
- 入力値の絶対値(常に0以上の数値)
基本的な使用例
単純な数値の絶対値
SELECT ABS(-25) AS result;
-- 結果: 25
正の数の場合
SELECT ABS(15) AS result;
-- 結果: 15(変化なし)
ゼロの場合
SELECT ABS(0) AS result;
-- 結果: 0
実践的な使用例
例1:取引データでの絶対値計算
サンプルテーブル:transactions
CREATE TABLE transactions (
id INT PRIMARY KEY,
customer_id INT,
amount DECIMAL(10,2),
transaction_date DATE
);
INSERT INTO transactions VALUES
(1, 101, 1500.00, '2024-01-15'),
(2, 102, -800.50, '2024-01-16'),
(3, 103, 2200.00, '2024-01-17'),
(4, 104, -1200.75, '2024-01-18'),
(5, 105, 0.00, '2024-01-19');
基本的な絶対値の取得
SELECT
id,
customer_id,
amount,
ABS(amount) AS absolute_amount
FROM transactions;
実行結果
id | customer_id | amount | absolute_amount
---|-------------|----------|----------------
1 | 101 | 1500.00 | 1500.00
2 | 102 | -800.50 | 800.50
3 | 103 | 2200.00 | 2200.00
4 | 104 | -1200.75 | 1200.75
5 | 105 | 0.00 | 0.00
例2:売上と予算の差異分析
サンプルテーブル:sales_budget
CREATE TABLE sales_budget (
month_year VARCHAR(7),
actual_sales DECIMAL(12,2),
budget_sales DECIMAL(12,2)
);
INSERT INTO sales_budget VALUES
('2024-01', 850000.00, 800000.00),
('2024-02', 720000.00, 750000.00),
('2024-03', 920000.00, 900000.00),
('2024-04', 680000.00, 800000.00);
差異の絶対値計算
SELECT
month_year,
actual_sales,
budget_sales,
(actual_sales - budget_sales) AS difference,
ABS(actual_sales - budget_sales) AS absolute_difference
FROM sales_budget;
実行結果
month_year | actual_sales | budget_sales | difference | absolute_difference
-----------|--------------|--------------|------------|-------------------
2024-01 | 850000.00 | 800000.00 | 50000.00 | 50000.00
2024-02 | 720000.00 | 750000.00 | -30000.00 | 30000.00
2024-03 | 920000.00 | 900000.00 | 20000.00 | 20000.00
2024-04 | 680000.00 | 800000.00 | -120000.00 | 120000.00
例3:在庫管理での過不足計算
サンプルテーブル:inventory
CREATE TABLE inventory (
product_id INT,
product_name VARCHAR(50),
current_stock INT,
required_stock INT
);
INSERT INTO inventory VALUES
(1, 'ノートPC', 45, 50),
(2, 'マウス', 120, 100),
(3, 'キーボード', 30, 40),
(4, 'モニター', 25, 20);
在庫の過不足絶対値
SELECT
product_id,
product_name,
current_stock,
required_stock,
(current_stock - required_stock) AS stock_difference,
ABS(current_stock - required_stock) AS stock_variance
FROM inventory;
WHERE句でのABS関数の活用

条件フィルタリングでの使用
一定の差異以上のデータを抽出
SELECT *
FROM sales_budget
WHERE ABS(actual_sales - budget_sales) > 50000;
在庫不足の商品を抽出
SELECT *
FROM inventory
WHERE ABS(current_stock - required_stock) > 10
AND current_stock < required_stock;
ORDER BY句での並べ替え
差異の絶対値で並べ替え
SELECT
month_year,
actual_sales,
budget_sales,
ABS(actual_sales - budget_sales) AS variance
FROM sales_budget
ORDER BY ABS(actual_sales - budget_sales) DESC;
集計関数との組み合わせ
平均絶対偏差の計算
SELECT
AVG(ABS(actual_sales - budget_sales)) AS avg_absolute_variance
FROM sales_budget;
最大絶対差異の特定
SELECT
month_year,
MAX(ABS(actual_sales - budget_sales)) AS max_variance
FROM sales_budget
GROUP BY month_year;
合計絶対値の計算
SELECT
SUM(ABS(amount)) AS total_absolute_amount
FROM transactions;
データベース別の対応状況
主要RDBMS対応表
データベース | ABS関数対応 | 注意事項 |
---|---|---|
MySQL | ○ | 標準対応 |
PostgreSQL | ○ | 標準対応 |
SQL Server | ○ | 標準対応 |
Oracle | ○ | 標準対応 |
SQLite | ○ | 標準対応 |
データベース固有の特徴
MySQL
-- 小数点以下の桁数指定
SELECT ROUND(ABS(amount), 2) FROM transactions;
PostgreSQL
-- 型キャストとの組み合わせ
SELECT ABS(amount::NUMERIC(10,2)) FROM transactions;
SQL Server
-- 通貨型での使用
SELECT ABS(CAST(amount AS MONEY)) FROM transactions;
高度な活用例

例1:移動平均との差異計算
WITH moving_avg AS (
SELECT
month_year,
actual_sales,
AVG(actual_sales) OVER (
ORDER BY month_year
ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
) AS moving_average
FROM sales_budget
)
SELECT
month_year,
actual_sales,
moving_average,
ABS(actual_sales - moving_average) AS deviation_from_avg
FROM moving_avg;
例2:パーセンタイル計算との組み合わせ
WITH percentiles AS (
SELECT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY amount) AS median_amount
FROM transactions
)
SELECT
t.id,
t.amount,
p.median_amount,
ABS(t.amount - p.median_amount) AS deviation_from_median
FROM transactions t
CROSS JOIN percentiles p;
例3:地理的距離の近似計算
CREATE TABLE locations (
id INT,
name VARCHAR(50),
latitude DECIMAL(10,6),
longitude DECIMAL(10,6)
);
-- 2点間の簡易距離計算(実際はより複雑な式を使用)
SELECT
a.name AS location_a,
b.name AS location_b,
ABS(a.latitude - b.latitude) + ABS(a.longitude - b.longitude) AS simple_distance
FROM locations a
CROSS JOIN locations b
WHERE a.id != b.id;
パフォーマンスの考慮事項
インデックスの活用
ABS関数を使った条件での注意点
-- インデックスが効きにくい例
SELECT * FROM transactions WHERE ABS(amount) > 1000;
-- より効率的な書き方
SELECT * FROM transactions
WHERE amount > 1000 OR amount < -1000;
計算コストの最適化
関数を複数回呼び出す場合
-- 非効率な例
SELECT
amount,
ABS(amount) AS abs_amount,
CASE WHEN ABS(amount) > 1000 THEN 'High' ELSE 'Low' END AS category
FROM transactions;
-- 効率的な例(WITH句使用)
WITH calculated AS (
SELECT
amount,
ABS(amount) AS abs_amount
FROM transactions
)
SELECT
amount,
abs_amount,
CASE WHEN abs_amount > 1000 THEN 'High' ELSE 'Low' END AS category
FROM calculated;
エラーハンドリングと注意点

NULL値の処理
-- NULL値を含むデータの処理
SELECT
amount,
ABS(COALESCE(amount, 0)) AS safe_absolute_value
FROM transactions;
データ型の注意事項
整数オーバーフローの回避
-- 大きな負の整数の場合の注意
-- -2147483648 (INT型の最小値)の絶対値は注意が必要
SELECT
CASE
WHEN value = -2147483648 THEN 2147483648.0
ELSE ABS(value)
END AS safe_abs
FROM large_numbers;
浮動小数点数の精度
-- 浮動小数点の精度を考慮した比較
SELECT *
FROM measurements
WHERE ABS(measured_value - expected_value) < 0.001; -- 許容誤差
実用的なSQL作成パターン
パターン1:異常値検出
WITH stats AS (
SELECT
AVG(amount) AS avg_amount,
STDDEV(amount) AS stddev_amount
FROM transactions
)
SELECT
t.*,
ABS(t.amount - s.avg_amount) / s.stddev_amount AS z_score
FROM transactions t
CROSS JOIN stats s
WHERE ABS(t.amount - s.avg_amount) > 2 * s.stddev_amount;
パターン2:期間比較分析
SELECT
current_month.month_year,
current_month.actual_sales AS current_sales,
previous_month.actual_sales AS previous_sales,
ABS(current_month.actual_sales - previous_month.actual_sales) AS month_to_month_change
FROM sales_budget current_month
LEFT JOIN sales_budget previous_month
ON DATE_ADD(STR_TO_DATE(previous_month.month_year, '%Y-%m'), INTERVAL 1 MONTH)
= STR_TO_DATE(current_month.month_year, '%Y-%m');
パターン3:グループ別集計
SELECT
customer_id,
COUNT(*) AS transaction_count,
SUM(ABS(amount)) AS total_transaction_volume,
AVG(ABS(amount)) AS avg_transaction_size
FROM transactions
GROUP BY customer_id
HAVING SUM(ABS(amount)) > 5000;
よくある質問

ABS関数とは別の方法で絶対値を求めることはできますか?
はい、CASE文を使用する方法があります:
SELECT
amount,
CASE
WHEN amount >= 0 THEN amount
ELSE -amount
END AS manual_absolute_value
FROM transactions;
ただし、ABS関数の方が簡潔で読みやすく、パフォーマンスも優れています。
ABS関数は文字列や日付型でも使用できますか?
ABS関数は数値型専用です。文字列や日付型では使用できません。日付の差異を求める場合は:
-- 日付の差の絶対値
SELECT ABS(DATEDIFF(date1, date2)) AS day_difference
FROM date_table;
非常に大きな数値でABS関数を使用する際の注意点は?
整数型の最小値(例:-2147483648)の絶対値は、同じ型の最大値を超える可能性があります。このような場合は:
-- より大きなデータ型を使用
SELECT ABS(CAST(large_negative_number AS BIGINT))
FROM large_numbers;
パフォーマンスを向上させるコツはありますか?
効率化のポイント:
- WHERE句でのABS使用を避ける:可能であれば範囲指定に変換
- 計算結果の再利用:WITH句やサブクエリで一度計算した結果を活用
- 適切なインデックス:元の列にインデックスを作成
- データ型の最適化:必要以上に大きなデータ型を避ける
まとめ
SQLのABS関数は、数値データ分析において非常に重要な役割を果たします。
重要なポイント
- 基本構文:
ABS(数値)
で絶対値を取得 - 幅広い用途:差異分析、統計計算、データクリーニング
- 集計関数との組み合わせ:より高度な分析が可能
- パフォーマンス考慮:WHERE句での使用は慎重に
用途別活用例
用途 | 典型的な使用例 | ポイント |
---|---|---|
差異分析 | 予算と実績の比較 | 正負を問わず差の大きさを把握 |
異常値検出 | 平均からの偏差計算 | 統計的な分析基盤 |
距離計算 | 位置情報の近似距離 | 簡易的な距離測定 |
在庫管理 | 過不足の絶対量 | 管理上の優先度判定 |
コメント