質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

4回答

6623閲覧

SQLの計算およびインサート

freeair.

総合スコア15

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2016/09/27 11:30

編集2022/01/12 10:55

SQL文で登録されているデータを計算し、
計算したデータを同じテーブルに登録するような処理を自動で行うことは可能でしょうか。

1つ目 2つ目 3つ目 100 100 100 200 300 200 400 400 200

という様なテーブルがあったとしたら

1つ目 2つ目 3つ目 合計 100 100 100 300 200 300 200 700 400 400 200 1000

こんな感じで合計をだしたカラムを作りたいです。

追記--
合計のカラムには最初は値が入ってない想定です。(1つ目2つ目3つ目が変更されるのでそれに準じて合計の値も変更が自動でされる)
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2016/09/27 11:49

データベースエンジンは何でしょうか。
退会済みユーザー

退会済みユーザー

2016/09/27 13:29

合計という列は、初めからテーブルに存在するのですか?1つ目〜3つ目が既に登録されているところから、合計を計算して、合計列に入れる(更新する)のですか?
guest

回答4

0

MySQL5.7 をお使いでしたら、ジェネレーテッド・カラムを使うのが良さそうです。
https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_generated_column

A column whose value is derived on demand by computing a set of expressions or functions.

これを使用すると、
「1つ目2つ目3つ目が変更されるのでそれに準じて合計の値も変更が自動でされる」
を、実現できます。

以下の例ではcol_sumがジェネレーテッド・カラムで、col_1 + col_2 + col_3の結果を表現しています。

sql

1mysql> CREATE TABLE tbl ( 2 -> col_1 int, 3 -> col_2 int, 4 -> col_3 int, 5 -> col_sum int AS (col_1 + col_2 + col_3) 6 -> ); 7Query OK, 0 rows affected (0.10 sec) 8 9mysql> INSERT INTO tbl (col_1, col_2, col_3) VALUES 10 -> (100, 100, 100), 11 -> (200, 300, 200), 12 -> (400, 400, 200); 13Query OK, 3 rows affected (0.00 sec) 14Records: 3 Duplicates: 0 Warnings: 0 15 16mysql> SELECT * FROM tbl; 17+-------+-------+-------+---------+ 18| col_1 | col_2 | col_3 | col_sum | 19+-------+-------+-------+---------+ 20| 100 | 100 | 100 | 300 | 21| 200 | 300 | 200 | 700 | 22| 400 | 400 | 200 | 1000 | 23+-------+-------+-------+---------+ 243 rows in set (0.00 sec) 25 26mysql> UPDATE tbl SET col_3 = col_3 * 2; 27Query OK, 3 rows affected (0.00 sec) 28Rows matched: 3 Changed: 3 Warnings: 0 29 30mysql> SELECT * FROM tbl; 31+-------+-------+-------+---------+ 32| col_1 | col_2 | col_3 | col_sum | 33+-------+-------+-------+---------+ 34| 100 | 100 | 200 | 400 | 35| 200 | 300 | 400 | 900 | 36| 400 | 400 | 400 | 1200 | 37+-------+-------+-------+---------+ 383 rows in set (0.00 sec)

MySQL5.6 以前をお使いであれば、トリガーを使用すれば同様のことが実現できます。
https://dev.mysql.com/doc/refman/5.6/ja/create-trigger.html

トリガーとは、テーブルに関連付けられ、そのテーブルに対して特定のイベントが発生するとアクティブ化される名前付きデータベースオブジェクトのことです。

対象のテーブルに対して INSERT および UPDATE が実行された際にcol_sumの値を再計算するトリガーを作成すればよいです。

sql

1mysql> CREATE TABLE tbl_2 ( 2 -> col_1 int, 3 -> col_2 int, 4 -> col_3 int, 5 -> col_sum int 6 -> ); 7Query OK, 0 rows affected (0.02 sec) 8 9mysql> CREATE TRIGGER ins_sum BEFORE INSERT ON tbl_2 FOR EACH ROW SET NEW.col_sum = NEW.col_1 + NEW.col_2 + NEW.col_3; 10Query OK, 0 rows affected (0.01 sec) 11 12mysql> CREATE TRIGGER upd_sum BEFORE UPDATE ON tbl_2 FOR EACH ROW SET NEW.col_sum = NEW.col_1 + NEW.col_2 + NEW.col_3; 13Query OK, 0 rows affected (0.00 sec) 14 15mysql> INSERT INTO tbl_2 (col_1, col_2, col_3) VALUES 16 -> (100, 100, 100), 17 -> (200, 300, 200), 18 -> (400, 400, 200); 19Query OK, 3 rows affected (0.00 sec) 20Records: 3 Duplicates: 0 Warnings: 0 21 22mysql> SELECT * FROM tbl_2; 23+-------+-------+-------+---------+ 24| col_1 | col_2 | col_3 | col_sum | 25+-------+-------+-------+---------+ 26| 100 | 100 | 100 | 300 | 27| 200 | 300 | 200 | 700 | 28| 400 | 400 | 200 | 1000 | 29+-------+-------+-------+---------+ 303 rows in set (0.00 sec) 31 32mysql> UPDATE tbl_2 SET col_3 = col_3 * 2; 33Query OK, 3 rows affected (0.01 sec) 34Rows matched: 3 Changed: 3 Warnings: 0 35 36mysql> SELECT * FROM tbl_2; 37+-------+-------+-------+---------+ 38| col_1 | col_2 | col_3 | col_sum | 39+-------+-------+-------+---------+ 40| 100 | 100 | 200 | 400 | 41| 200 | 300 | 400 | 900 | 42| 400 | 400 | 400 | 1200 | 43+-------+-------+-------+---------+ 443 rows in set (0.00 sec)

追記

MySQLでは、col_1, col_2, col_3のいずれかが NULL の場合、

col_1 + col_2 + col_3 = NULL

となります。
https://dev.mysql.com/doc/refman/5.6/ja/problems-with-null.html

NULL を含む式は、式に関連する演算子および関数のドキュメントに示されている場合を除き、常に NULL 値を生成します。

"合計をだしたカラム"に NULL が格納されるのを避けたい場合、
yambejp様のコメントにある通り、col_1, col_2, col_3に NOT NULL 制約をつけるか、
NULL を適切な値に変換した上で合計を計算するなどの対処をしてください。

投稿2016/09/28 03:41

編集2016/09/28 06:17
KiyoshiMotoki

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2016/09/28 04:31

KiyoshiMotokiさんの書き方を支持しますが 可能であればcol_1~3にNOT NULL属性をつけてデフォルトを0にするか 仕様上col_1~3のいずれかもしくは全部がNULLになる場合が想定されるなら それでも合計が出せるように SET NEW.col_sum = COALESCE(NEW.col_1,0) + COALESCE(NEW.col_2,0) + COALESCE(NEW.col_3,0); のような処理をいれると良いかもしれませんね
KiyoshiMotoki

2016/09/28 06:18

yambejp様 ご指摘ありがとうございます。 確かに、おっしゃる通りですね。 回答に補足を追記させていただきました。
guest

0

あえて自動登録する、という主題から観点を外した回答をしてみます。

もしも見せ方としてそ合計列が欲しいだけで実テーブルへのこだわりがないとしたら、
一般的なDBMSが漏れなくサポートしてるであろうビュー機能を用いるという解決策もあると思います。
(Oracle、SQL Sever、MySQLなどいずれもサポートされており、標準SQLの範囲なのでベンダ依存もほとんどありません。)

MySQLでビューを用いるなら下記のような感じで定義します。

SQL

1CREATE OR REPLACE VIEW sample_view AS 2SELECT 3 col1 4, col2 5, col3 6, col1 + col2 + col3 AS total 7FROM 8 sample_table

利用するときはビュー名で下記のようにアクセスします。

SQL

1SELECT 2 col1 3, col2 4, col3 5, total 6FROM 7 sample_view

ビューのメリットとしては、
実体を持たないという特徴があるため、
実テーブル側の値やデータ数が変わった場合も、自動計算して出力してくれる点です。

ただしデメリットもまた実体を持たないことで、
内部的にはビューで定義したSELECT句が起動されるだけなので、
下手な使い方をするとパフォーマンス的に不利となります。

ちなみにビューを経由したINSERTやUPDATEなどには色々と制約があるので、
その際は素直に実テーブルに対して行うと良いでしょう。

SQL

1INSERT INTO sample_table (col1, col2, col3) VALUES (100, 500, 400)

尚ビューを用いる場合も例に漏れず、
KiyoshiMotokiさんの回答にあるようなNULL演算の問題が起こり得ます。
これはMySQLに限った話ではなく、
一般的DBMSは全てこのような挙動を取ります。
参考までにNULLの話題を扱ったQAもありますので、
興味があるようでしたら一読して下さい。

対策方法としては、
実テーブル側にカラムにNOT NULL制約をかけるか、
SELECTする際にベンダ拡張のIFNULL関数か標準SQL関数のCOALESCE関数を利用してNULLをエスケープするかしておきましょう。

投稿2016/09/28 10:15

編集2016/09/28 10:29
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

追記
自動でという前提を忘れていたので、下記は忘れてください。


合計のカラムは最初からあるという前提ですよね。
単純に全レコードをそれぞれけいさんするのであれば次のようになります。
(1つ目:n1、2つ目:n2、3つ目:n3、合計:total、とする)

SQL

1update tbl set total=n1+n2+n3

特定のレコードのみなど条件を付けたいのであれば、WHERE句を指定することもできます。

SQL

1update tbl set total=n1+n2+n3 where 条件...

投稿2016/09/28 00:13

編集2016/09/28 07:20
ttyp03

総合スコア16996

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Oracle12.1.0EE 64bit for Windows

CREATE TABLE TAB1
(
NUM1 NUMBER(5)
, NUM2 NUMBER(5)
, NUM3 NUMBER(5)
) ;

INSERT INTO TAB1(NUM1, NUM2, NUM3) VALUES(100, 100, 100) ;
INSERT INTO TAB1(NUM1, NUM2, NUM3) VALUES(200, 300, 200) ;
INSERT INTO TAB1(NUM1, NUM2, NUM3) VALUES(400, 400, 200) ;
COMMIT ;

-- と、ここまでが準備

-- 合計を取得する時に計算するので合計は通常列では持ちません。

COLUMN NUM1 HEADING "1つ目"
COLUMN NUM2 HEADING "2つ目"
COLUMN NUM3 HEADING "3つ目"
COLUMN GOKEI HEADING "合計"
SELECT T1.NUM1
, T1.NUM2
, T1.NUM3
, T1.NUM1 + T1.NUM2 + T1.NUM3 AS GOKEI
FROM TAB1 T1 ;

1つ目 2つ目 3つ目 合計

100 100 100 300 200 300 200 700 400 400 200 1000

投稿2016/09/27 12:04

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

freeair.

2016/09/28 00:14 編集

ありがとうございます。可能であれば、計算した値を実際にテーブルに登録するところまでの 動きを作りたいと思ってます。よろしくお願いします。
Orlofsky

2016/09/28 00:24

テーブル TAB1 に GOKEI 列があったとして、 UPDATE TAB1 T1 SET T1.GOKEI = T1.NUM1 + T1.NUM2 + T1.NUM3 ;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問