UNIONとUNION ALLの違いは、重複した行を1行にまとめるかどうかです。UNIONは2つのSELECT結果を縦につないだあと重複を取り除き、UNION ALLは重複も含めてそのまま全行を返します。 重複を取り除く処理がないぶん、UNION ALLのほうが速く動きます。

この記事では、同じサンプル表に対して PostgreSQL 16.15・MySQL 8.0.46・SQLite 3.45.1 で実行した結果を並べて、UNIONとUNION ALLの違いを確認します。さらに、100万行でのEXPLAINと実行時間、列数や型が合わないときのエラー全文、ORDER BY・LIMITを書く位置と括弧、INTERSECT・EXCEPTとの使い分けまで、実際の出力つきでまとめました。

MySQL 8.0 は2026年4月にサポートが終了しています。本記事の検証は手元の 8.0.46 で行いましたが、ここで扱う UNION・UNION ALL・INTERSECT・EXCEPT の書き方は MySQL 8.4/9.7 でも同じ手順で使えます(INTERSECT・EXCEPT は 8.0.31 以降の機能です)。

UNION・UNION ALLの早見表

項目 UNION UNION ALL
重複行 1行にまとめる そのまま残す
行の順序 保証されない(ORDER BY で指定) 保証されない(ORDER BY で指定)
速さ 重複排除の並べ替え・ハッシュ処理がある 追加の処理なし
100万行の実測(PostgreSQL 16) 276〜296 ms 50〜60 ms
100万行の実測(MySQL 8.0) 1.75〜1.91 秒 0.72 秒
NULL 同士 同じ値として1行にまとめる そのまま残す
向いている場面 重複を除いた一覧を作る 重複がない/重複も数えたい/速さを優先

書き方のルール(全DB共通)

ルール 内容
列数 すべてのSELECTで同じ数にそろえる
型 同じ位置の列は互換性のある型にそろえる(必要なら CAST)
列名 1つ目のSELECTの列名(別名)が結果の列名になる
ORDER BY 最後に1回だけ書く。並べ替えに使えるのは1つ目の列名か列番号
個別の LIMIT 各SELECTを括弧(SQLiteはサブクエリ)で囲む
出所を残す 'online' AS source のような定数列を足す

集合演算の使い分け

やりたいこと 演算子
AとBを合わせた一覧(重複なし) UNION
AとBを合わせた全行 UNION ALL
AとBの両方にある行 INTERSECT
AにあってBにない行 EXCEPT(Oracle は MINUS も可)
AとBの列を横に並べる JOIN(集合演算ではない)

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「SQL UNIONとUNION ALLの違い|実行結果つき使い方とエラー対処」

サンプルデータを用意する

オンライン会員と店頭会員の2つの表を用意します。列名がそれぞれ違い、2人(佐藤・鈴木)が両方に登録されている想定です。

DROP TABLE IF EXISTS online_members;
DROP TABLE IF EXISTS store_members;
CREATE TABLE online_members (id INT PRIMARY KEY, name VARCHAR(20), email VARCHAR(50), points INT);
CREATE TABLE store_members  (member_no INT PRIMARY KEY, full_name VARCHAR(20), mail VARCHAR(50), joined DATE);
INSERT INTO online_members VALUES
 (1,'佐藤','sato@example.com',120),(2,'鈴木','suzuki@example.com',80),(3,'高橋','takahashi@example.com',200);
INSERT INTO store_members VALUES
 (101,'鈴木','suzuki@example.com','2026-04-01'),(102,'田中','tanaka@example.com','2026-05-10'),(103,'佐藤','sato@example.com','2026-06-20');

PostgreSQL・MySQL・SQLiteのどれでもそのまま実行できます(MySQLは mysql --default-character-set=utf8mb4 で接続)。

UNIONとUNION ALLの結果を並べて比べる

-- UNION:重複を除く
SELECT name, email FROM online_members
UNION
SELECT full_name, mail FROM store_members
ORDER BY email;

-- UNION ALL:重複も残す
SELECT name, email FROM online_members
UNION ALL
SELECT full_name, mail FROM store_members
ORDER BY email;

実行結果(PostgreSQL 16.15。MySQL 8.0.46・SQLite 3.45.1 も同じ行)

UNION(4行) UNION ALL(6行)
佐藤 sato@example.com 佐藤 sato@example.com
鈴木 suzuki@example.com 佐藤 sato@example.com
高橋 takahashi@example.com 鈴木 suzuki@example.com
田中 tanaka@example.com 鈴木 suzuki@example.com
高橋 takahashi@example.com
田中 tanaka@example.com

UNIONは「佐藤」「鈴木」が1行ずつ、UNION ALLは2行ずつ残りました。 重複かどうかは、SELECTした列の値がすべて一致するかで判定されます。どちらかの表で email の大文字小文字が違えば、別の行として残ります。

結果の列名は name, email です。列名は1つ目のSELECT(online_members)から取られ、2つ目の full_name, mail は使われません。

どちらの表から来た行かを残す

SELECT 'online' AS source, name, email FROM online_members
UNION ALL
SELECT 'store', full_name, mail FROM store_members
ORDER BY email, source;
 source | name |         email
--------+------+-----------------------
 online | 佐藤 | sato@example.com
 store  | 佐藤 | sato@example.com
 online | 鈴木 | suzuki@example.com
 store  | 鈴木 | suzuki@example.com
 online | 高橋 | takahashi@example.com
 store  | 田中 | tanaka@example.com
(6 rows)

定数の列を足すと、どの表から来た行かがわかります。 この形にすると各行が別の値になるため、UNIONにしても行は減りません。出所の列を付けるときは UNION ALL で十分です。

NULLは同じ値として扱われる

SELECT count(*) AS null_rows FROM (SELECT NULL AS x UNION SELECT NULL) t;

PostgreSQL・MySQL・SQLiteのすべてで null_rows = 1 でした。WHERE x = NULL では一致しないNULL同士も、UNIONの重複判定では同じ値として1行にまとめられます。

UNION ALLが速い理由をEXPLAINと実測で確かめる

50万行ずつの2つのログ表(うち25万行が重複)で、UNIONとUNION ALLを比べました。

-- PostgreSQL 16
CREATE TABLE log_a (id int PRIMARY KEY, user_id int, action text);
CREATE TABLE log_b (id int PRIMARY KEY, user_id int, action text);
INSERT INTO log_a SELECT g, g % 50000, 'view-' || (g % 1000) FROM generate_series(1,500000) g;
INSERT INTO log_b SELECT g, g % 50000, 'view-' || (g % 1000) FROM generate_series(250001,750000) g;
ANALYZE log_a; ANALYZE log_b;

EXPLAIN ANALYZE
SELECT count(*) FROM (SELECT id, user_id, action FROM log_a
                      UNION
                      SELECT id, user_id, action FROM log_b) t;

PostgreSQL 16:UNIONは Sort + Unique が入る

UNIONの実行計画(PostgreSQL 16.15、work_mem 4MB)

 Aggregate  (actual time=589.626..589.628 rows=1 loops=1)
   ->  Unique  (actual time=323.974..536.301 rows=750000 loops=1)
         ->  Sort  (actual time=323.971..411.337 rows=1000000 loops=1)
               Sort Key: log_a.id, log_a.user_id, log_a.action
               Sort Method: external merge  Disk: 26400kB
               ->  Append  (actual time=0.016..153.329 rows=1000000 loops=1)
                     ->  Seq Scan on log_a  (actual time=0.015..38.943 rows=500000 loops=1)
                     ->  Seq Scan on log_b  (actual time=0.010..38.549 rows=500000 loops=1)
 Execution Time: 660.722 ms

UNION ALLの実行計画

 Finalize Aggregate  (actual time=134.600..141.599 rows=1 loops=1)
   ->  Gather  (actual time=134.426..141.590 rows=3 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Partial Aggregate  (actual time=109.819..109.821 rows=1 loops=3)
               ->  Parallel Append  (actual time=0.009..87.673 rows=333333 loops=3)
                     ->  Parallel Seq Scan on log_a  (actual time=0.009..22.534 rows=166667 loops=3)
                     ->  Parallel Seq Scan on log_b  (actual time=0.012..29.381 rows=250000 loops=2)
 Execution Time: 141.633 ms

(cost の表示は省略しています。)UNIONでは100万行をすべての列で並べ替え(Sort)、隣り合う同じ行を1つにする(Unique)処理が入ります。 並べ替えがメモリ(work_mem)に収まらず、ディスクを26MBほど使っています。UNION ALLは2つの表を順につなぐ(Append)だけなので、並列実行も使われています。

MySQL 8.0:UNIONは一時テーブルで重複を除く

EXPLAIN SELECT id, user_id, action FROM log_a UNION     SELECT id, user_id, action FROM log_b;
EXPLAIN SELECT id, user_id, action FROM log_a UNION ALL SELECT id, user_id, action FROM log_b;
-- UNION
| id | select_type  | table      | type | rows   | Extra           |
|  1 | PRIMARY      | log_a      | ALL  | 499567 | NULL            |
|  2 | UNION        | log_b      | ALL  | 499208 | NULL            |
|  3 | UNION RESULT | <union1,2> | ALL  |   NULL | Using temporary |

-- UNION ALL
| id | select_type | table | type | rows   | Extra |
|  1 | PRIMARY     | log_a | ALL  | 499567 | NULL  |
|  2 | UNION       | log_b | ALL  | 499208 | NULL  |

(列の一部を省略しています。)EXPLAIN ANALYZE で件数を数えた結果です。

-- UNION
-> Aggregate: count(0)  (actual time=2068..2068 rows=1 loops=1)
    -> Table scan on t  (actual time=1859..2026 rows=750000 loops=1)
        -> Union materialize with deduplication  (actual time=1859..1859 rows=750000 loops=1)

-- UNION ALL
-> Aggregate: count(0)  (actual time=899..899 rows=1 loops=1)
    -> Table scan on t  (actual time=616..847 rows=1e+6 loops=1)
        -> Union all materialize  (actual time=616..616 rows=1e+6 loops=1)

MySQLのUNIONは UNION RESULT(Using temporary)として一時テーブルに書き込みながら重複を取り除きます(Union materialize with deduplication)。 UNION ALLの単独のSELECTでは UNION RESULT の行がなく、一時テーブルを使わずに結果を返しています。

実行時間(3回ずつ)

クエリ(結果件数) PostgreSQL 16.15(psql \timing) MySQL 8.0.46(mysql -vvv)
UNION(750,000件) 295.743 / 288.084 / 276.073 ms 1.91 / 1.75 / 1.79 秒
UNION ALL(1,000,000件) 60.043 / 55.585 / 50.104 ms 0.72 / 0.72 / 0.72 秒

どちらのDBでもUNION ALLのほうが速く、PostgreSQLで約5倍、MySQLで約2.5倍の差でした。 同じコンテナ上での目安の値ですが、差の理由は実行計画の「重複排除の処理」の有無で説明できます。

どちらを使うかの判断表

状況 選ぶもの 理由
主キーの範囲が分かれているなど、重複が起こらない UNION ALL 重複排除の処理が不要
出所の定数列を付けている UNION ALL 行がすべて別の値になる
件数や合計を数えたい(重複も数える) UNION ALL UNIONだと同じ行が減って数がずれる
一覧から同じ行を除きたい UNION 重複排除がそのまま目的
大量の行から重複を除きたい UNION ALL + 必要な列だけ DISTINCT/GROUP BY 重複判定の列を絞ると処理が軽くなる

重複行を見つけて消す方法そのものは「SQLで重複データを抽出・削除する方法」の記事でまとめています。

UNIONでよくあるエラーと直し方

列数が合わない

SELECT name, email FROM online_members
UNION
SELECT full_name FROM store_members;
DB エラー全文
PostgreSQL 16 ERROR: each UNION query must have the same number of columns
MySQL 8.0 ERROR 1222 (21000): The used SELECT statements have a different number of columns
SQLite 3.45 Parse error: SELECTs to the left and right of UNION do not have the same number of result columns

足りない列は NULL AS email のように補ってそろえます。

SELECT name, email FROM online_members
UNION
SELECT full_name, NULL FROM store_members;

型が合わない

数値の列(points)と文字列の列(mail)を同じ位置に置いた場合です。

SELECT name, points FROM online_members
UNION
SELECT full_name, mail FROM store_members;
-- PostgreSQL 16
ERROR:  UNION types integer and character varying cannot be matched
LINE 1: ...oints FROM online_members UNION SELECT full_name, mail FROM ...
                                                             ^

MySQL 8.0 と SQLite ではエラーにならず、数値と文字列が同じ列に混ざって返りました。

-- MySQL 8.0
+--------+--------------------+
| name   | points             |
+--------+--------------------+
| 佐藤   | 120                |
| 鈴木   | 80                 |
| 高橋   | 200                |
| 鈴木   | suzuki@example.com |
| 田中   | tanaka@example.com |
| 佐藤   | sato@example.com   |
+--------+--------------------+

整数と日付(points と joined)でも同じで、PostgreSQLは ERROR: UNION types integer and date cannot be matched、MySQLとSQLiteは日付が文字列として混ざりました。エラーにならないDBでも、列の意味がずれていないかを確認することが大切です。 意図して混ぜるときは、型を明示的にそろえます。

-- PostgreSQL
SELECT name, CAST(points AS VARCHAR(20)) AS info FROM online_members
UNION ALL
SELECT full_name, mail FROM store_members
ORDER BY name;

-- MySQL(CAST の型は CHAR を使う)
SELECT name, CAST(points AS CHAR) AS info FROM online_members
UNION ALL
SELECT full_name, mail FROM store_members
ORDER BY name;

MySQLで CAST(points AS VARCHAR(20)) と書くと ERROR 1064 (42000): You have an error in your SQL syntax ... near 'VARCHAR(20)) AS info ...' になりました。MySQLの CAST では CHAR を指定します。

数値同士でも型の扱いはDBで少し違います。SELECT 1 AS n UNION SELECT 1.0 UNION SELECT 2; の結果は次のとおりでした。

DB 結果
PostgreSQL 16 1、2(1 と 1.0 を同じ値として1行に)
MySQL 8.0 1.0、2.0(DECIMAL にそろう)
SQLite 3.45 1.0、2(行ごとに型が残る)

ORDER BY を途中に書いた

SELECT name, email FROM online_members ORDER BY name
UNION
SELECT full_name, mail FROM store_members;
DB エラー全文
PostgreSQL 16 ERROR: syntax error at or near "UNION"
MySQL 8.0 ERROR 1064 (42000): You have an error in your SQL syntax; ... near 'UNION SELECT full_name, mail FROM store_members' at line 1
SQLite 3.45 Parse error: ORDER BY clause should come after UNION not before

ORDER BY は最後のSELECTの後ろに1回だけ書きます。 この ORDER BY は結果全体に効きます。

2つ目のSELECTの列名で並べ替えた

SELECT name, email FROM online_members
UNION
SELECT full_name, mail FROM store_members
ORDER BY mail;
-- PostgreSQL 16
ERROR:  column "mail" does not exist
LINE 1: ...ION SELECT full_name, mail FROM store_members ORDER BY mail;
                                                                  ^
DETAIL:  There is a column named "mail" in table "*SELECT* 2", but it cannot be referenced from this part of the query.

-- MySQL 8.0
ERROR 1054 (42S22): Unknown column 'mail' in 'order clause'

SQLite 3.45 ではエラーにならず、email 順に並びました。どのDBでも動く書き方は、1つ目のSELECTの列名(ORDER BY email)か列番号(ORDER BY 2)です。

ORDER BY・LIMITの書き方と括弧

全体を並べて件数を絞る

SELECT name, email FROM online_members
UNION ALL
SELECT full_name, mail FROM store_members
ORDER BY 2
LIMIT 3;
 name |       email
------+--------------------
 佐藤 | sato@example.com
 佐藤 | sato@example.com
 鈴木 | suzuki@example.com
(3 rows)

PostgreSQL・MySQL・SQLiteで同じ結果でした。最後の ORDER BY と LIMIT は、つないだ後の結果全体に効きます。

各SELECTごとに件数を絞る(ポイント最多の1人+最新入会の1人)

-- PostgreSQL・MySQL:括弧で囲む
(SELECT name, email FROM online_members ORDER BY points DESC LIMIT 1)
UNION ALL
(SELECT full_name, mail FROM store_members ORDER BY joined DESC LIMIT 1);
 name |         email
------+-----------------------
 高橋 | takahashi@example.com
 佐藤 | sato@example.com
(2 rows)

SQLite 3.45 では括弧で囲んだ形は Parse error near line 1: near "(": syntax error になりました。サブクエリにすると、PostgreSQL・MySQL・SQLiteのすべてで同じ結果になりました。

-- 3DB共通で動く書き方
SELECT * FROM (SELECT name, email FROM online_members ORDER BY points DESC LIMIT 1) AS a
UNION ALL
SELECT * FROM (SELECT full_name, mail FROM store_members ORDER BY joined DESC LIMIT 1) AS b;

括弧もサブクエリもない状態で各SELECTに付けた ORDER BY・LIMIT は、全体に付けたものとして扱われるかエラーになります。 個別に絞りたいときは、必ず囲みます。

INTERSECT・EXCEPTとの使い分け

-- 両方に登録している会員
SELECT name, email FROM online_members
INTERSECT
SELECT full_name, mail FROM store_members
ORDER BY email;

-- オンラインだけに登録している会員
SELECT name, email FROM online_members
EXCEPT
SELECT full_name, mail FROM store_members
ORDER BY email;

実行結果(PostgreSQL 16・MySQL 8.0.46・SQLite 3.45 で同じ)

INTERSECT EXCEPT
佐藤 sato@example.com 高橋 takahashi@example.com
鈴木 suzuki@example.com

MySQLの INTERSECT・EXCEPT は 8.0.31 で追加された機能です。 それより前の MySQL では、EXISTS や NOT EXISTS を使って同じ結果を書きます(EXISTS と IN の違いは別記事「SQLのEXISTSとINの違い」で扱っています)。MySQL 8.0.46 では INTERSECT ALL も動くことを確認しました。

flowchart LR
    A[online_members] --> U[UNION: AまたはB]
    B[store_members] --> U
    A --> I[INTERSECT: AかつB]
    B --> I
    A --> E[EXCEPT: AにあってBにない]
    B --> E

JOINとの違い

観点 UNION JOIN
つなぐ方向 縦(行を足す) 横(列を足す)
条件 列数・型をそろえる ON で結合条件を書く
結果の行数 2つの結果の行の合計(UNIONは重複を除く) 条件に合う組み合わせの数
例 オンライン会員と店頭会員の一覧を1つに 会員と注文をつないで会員名つきの注文一覧に

「同じ形の一覧を1つにまとめる」ならUNION、「別の情報を横に付け足す」ならJOINです。JOINの種類の違いは「SQLのJOINの違い」の記事で詳しく比較しています。

横持ちの列を縦に並べる(UNPIVOTの代わり)

四半期ごとの完了タスク数が列に並んでいる表を、行に並べ替える用途でも UNION ALL が使えます。

CREATE TABLE team_tasks (team VARCHAR(10), q1 INT, q2 INT, q3 INT);
INSERT INTO team_tasks VALUES ('A',10,12,9),('B',7,NULL,11);

SELECT team, 'q1' AS quarter, q1 AS done FROM team_tasks
UNION ALL
SELECT team, 'q2', q2 FROM team_tasks
UNION ALL
SELECT team, 'q3', q3 FROM team_tasks
ORDER BY team, quarter;
 team | quarter | done
------+---------+------
 A    | q1      |   10
 A    | q2      |   12
 A    | q3      |    9
 B    | q1      |    7
 B    | q2      |
 B    | q3      |   11
(6 rows)

UNPIVOT構文がないPostgreSQL・MySQL・SQLiteでも、UNION ALLで同じ形にできます(3DBで同じ結果を確認、MySQLでは空欄が NULL と表示)。縦持ちと横持ちの変換をまとめて扱う方法は「SQLで縦持ち⇔横持ち変換」の記事で紹介しています。

DB別の違い

SQL Server・Oracle の列は公式ドキュメントで確認した内容です(本記事では未実行)。

項目 PostgreSQL 16 MySQL 8.0 SQLite 3.45 SQL Server Oracle
UNION/UNION ALL 対応 対応 対応 対応 対応
INTERSECT/EXCEPT 対応 8.0.31以降 対応 対応 対応(MINUS も可)
INTERSECT ALL/EXCEPT ALL 対応 8.0.31以降 なし なし 対応(最新版の公式に記載)
型が違う列 エラー 暗黙に変換 そのまま混在 データ型の優先順位で決定 文字と数値の混在はエラー
2つ目の列名で ORDER BY エラー エラー 可 1つ目の列名を使う 1つ目の列名か別名を使う
各SELECTを括弧で囲む 可 可 不可(サブクエリで) 可 可
件数を絞る書き方 LIMIT LIMIT LIMIT TOP/OFFSET FETCH FETCH FIRST n ROWS ONLY

PostgreSQLとOracleは型の違いを厳しくエラーにし、MySQLとSQLiteは変換や混在で結果を返します。 複数のDBで動かすSQLでは、CASTで型をそろえ、ORDER BY は1つ目の列名か列番号で書くと安心です。

よくある質問

Q. UNIONの結果は、1つ目のSELECT→2つ目のSELECTの順に並びますか? A. 順序は保証されません。UNIONは重複排除のために並べ替えやハッシュを使うため、順番が入れ替わることがあります。UNION ALLでも並列実行などで変わる可能性があるため、順序が必要なら最後に ORDER BY を書きます。

Q. 3つ以上のSELECTをつなげますか? A. つなげます。UNION ALL と UNION を混ぜることもできますが、左から順に評価されるため意図がわかりにくくなります。混ぜるときは括弧で順序を明示します。

Q. WHERE はどこに書きますか? A. 各SELECTの中に書きます。つないだ後の結果を絞りたいときは、全体をサブクエリ(SELECT * FROM ( ... UNION ALL ... ) t WHERE ...)やWITH句で囲みます。

Q. MySQL 8.4 や 9.7 でも同じですか? A. 本記事のUNION・UNION ALL・INTERSECT・EXCEPT・括弧の書き方は 8.4/9.7 でも同じ手順で使えます。MySQL 8.0 の 8.0.31 より前のバージョンでは INTERSECT・EXCEPT が使えないため、EXISTS で書き換えます。

まとめ

  • UNIONは重複を除き、UNION ALLは全行を返す。重複判定はSELECTした全列の一致で、NULL同士も同じとみなす
  • UNION ALLが速いのは重複排除の処理がないから。100万行でPostgreSQLは約5倍、MySQLは約2.5倍の差だった
  • 列数と型をそろえる。PostgreSQLは型違いをエラーにし、MySQL・SQLiteは混ぜて返すので CAST で明示する
  • 列名は1つ目のSELECTから。ORDER BY は最後に1回、1つ目の列名か列番号で書く
  • 各SELECTに LIMIT を付けるときは括弧かサブクエリで囲む。SQLiteはサブクエリで書く
  • INTERSECT・EXCEPT で共通部分と差分。MySQLは 8.0.31 以降で使える
  • 縦につなぐならUNION、横に付け足すならJOIN

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「SQL UNIONとUNION ALLの違い|実行結果つき使い方とエラー対処」

株式会社RJCでは、SQLの集合演算の使い方を仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?