🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
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回答

863閲覧

主テーブルの全データを出しつつ結合したテーブルに条件を付ける方法(結合テーブルの条件に合致しない場合はNULLとする)

tomona

総合スコア37

MySQL

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

SQL

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

0グッド

1クリップ

投稿2019/09/23 06:28

以下のケースを想定して抽出方法をご教示頂けないでしょうか。

会計システムを作っています。
2種類の勘定科目マスター(自社の勘定科目、グループ会社用の勘定科目)があり、その変換表を作っています。

以下のテーブル構成となっています。
自社の勘定科目のテーブル:company_m_accounts
グループの勘定科目のテーブル:groupm_accounts
対応テーブル:company_t_map_accounts

自社の勘定科目に対応しているグループ会社の勘定科目が対応しているかグループ毎に確認したく、company_m_accountsの全データとそれに紐づくデータを取得する方法をご教示いただけますと幸いです。
以下のテストケースをご覧頂くとわかりやすいと思います。

SQL

1-- 勘定科目マスターの定義テーブルの作成 2DROP TABLE IF EXISTS company_m_accounts; 3 4CREATE TABLE company_m_accounts ( 5 company_id CHAR(3) NOT NULL, 6 account_id VARCHAR(255) NOT NULL, 7 PRIMARY KEY (company_id,account_id) 8) DEFAULT CHARSET=utf8; 9 10 11DROP TABLE IF EXISTS group_m_accounts; 12-- 勘定科目マスター(グループ別) 13CREATE TABLE group_m_accounts ( 14 group_id CHAR(3) NOT NULL, 15 group_account_id VARCHAR(255) NOT NULL, 16 PRIMARY KEY (group_id,group_account_id) 17) DEFAULT CHARSET=utf8; 18 19 20DROP TABLE IF EXISTS company_t_map_accounts; 21-- 勘定科目マッピングテーブル 22CREATE TABLE company_t_map_accounts ( 23 company_id CHAR(3) NOT NULL, 24 account_id VARCHAR(255) NOT NULL, 25 group_id CHAR(43) NOT NULL, 26 group_account_id VARCHAR(255) NOT NULL, 27 PRIMARY KEY (company_id,account_id,group_id,group_account_id) 28)DEFAULT CHARSET=utf8; 29 30-- 勘定科目レコードの投入 31INSERT INTO company_m_accounts VALUES('com','1000001'); 32INSERT INTO company_m_accounts VALUES('com','1000002'); 33INSERT INTO company_m_accounts VALUES('com','1000003'); 34INSERT INTO company_m_accounts VALUES('com','1100001'); 35INSERT INTO company_m_accounts VALUES('com','1110000'); 36 37 38-- グループ勘定科目レコードの投入 39INSERT INTO group_m_accounts VALUES('grp','1000001'); 40INSERT INTO group_m_accounts VALUES('grp','1000002'); 41INSERT INTO group_m_accounts VALUES('grp','1000003'); 42INSERT INTO group_m_accounts VALUES('grp','1100001'); 43INSERT INTO group_m_accounts VALUES('grp','1110000'); 44 45

作成したSQL

SQL

1SELECT A.account_id, C.group_account_id 2FROM company_m_accounts AS A 3LEFT OUTER JOIN company_t_map_accounts AS B 4ON A.company_id = B.company_id AND A.account_id = B.group_account_id 5LEFT OUTER JOIN group_m_accounts AS C 6ON B.group_id = C.group_id AND A.account_id = B.group_account_id 7WHERE A.company_id = 'com' AND B.group_id= 'grp';

想定される結果

account_idgroup_account_id
1000001NULL
1000002NULL
1000003NULL
1000004NULL
1000005NULL

上記のSelect文の場合、group_idで絞るためレコードがすべてNULLとなります。しかし、company_m_accountsのレコードはすべて抽出した上でgroup_account_idがNULLとなるようなレコードを抽出したいと考えています。
アドバイス頂けると幸いです。

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

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

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

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

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

Orlofsky

2019/09/23 06:41

company_t_map_accounts の INSERT が1行もないけど良いの?
tomona

2019/09/23 06:52

大丈夫です。 company_t_map_accountsは空欄のため結果としてgroup_idがNULLのレコードを取得したいためです。
sazi

2019/09/27 06:09

>変換表を作っています。 company_t_map_accountsという事ですよね? だとすると変換のルールというのは、account_id とgroup_account_idが等しい場合ですか? それだと、company_t_map_accountsを作る必要性を感じないのだけれど。
tomona

2019/09/30 08:42

>変換のルールというのは、account_id とgroup_account_idが等しい場合ですか? 必ずしも等しいとは限りません。
guest

回答4

0

変換表を作りたいとのことなので、こういう感じではないでしょうか。

SQL

1SELECT 2 D.group_id 3, A.account_id 4, C.group_account_id 5FROM 6 company_m_accounts AS A 7 CROSS JOIN 8 ( 9 SELECT 10 group_id 11 FROM 12 group_m_accounts 13 GROUP BY 14 group_id 15 ) AS D 16 LEFT OUTER JOIN 17 company_t_map_accounts AS B 18 ON B.company_id = A.company_id 19 AND B.account_id = A.account_id 20 LEFT OUTER JOIN 21 group_m_accounts AS C 22 ON C.group_id = D.group_id 23 AND C.group_account_id = B.group_account_id 24WHERE 25 A.company_id = 'com' 26-- AND D.group_id = 'grp'
group_idacount_idgroup_account_id
grp1000001NULL
grp1000002NULL
grp1000003NULL
grp1100001NULL
grp1110000NULL

投稿2019/09/24 02:52

KOZ6.0

総合スコア2707

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

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

0

なにがどうリレーションしているのかわからないですがこういうことですか?

SQL

1select t1.account_id,t3.group_account_id from company_m_accounts as t1 2left join company_t_map_accounts as t2 on t1.company_id = t2.company_id 3left join group_m_accounts as t3 on t2.group_account_id = t3.group_account_id

投稿2019/09/24 01:38

yambejp

総合スコア116683

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

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

0

ベストアンサー

SQL

1SELECT A.account_id, C.group_account_id 2FROM company_m_accounts AS A 3LEFT OUTER JOIN company_t_map_accounts AS B 4ON A.company_id = B.company_id AND A.account_id = B.group_account_id 5LEFT OUTER JOIN group_m_accounts AS C 6ON B.group_id = C.group_id AND B.group_account_id = C.group_account_id 7AND B.group_id= 'grp' 8WHERE A.company_id = 'com' ; 9

Cの結合条件がA.account_idとなっていたのがうまくとれない原因の一つです
グループでのしぼりこみはWHEREでやると全体がしぼりこまれてしたうためONの中でやると一致しないのもとれますよ

投稿2019/09/24 00:53

shirokuma4690

総合スコア154

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

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

tomona

2019/09/30 08:46

まさにこちらです! ONの中で条件指定が出来るのですね。大変勉強になりました。 ベストアンサーのみならず、皆様ご回答ありがとうございました。
guest

0

WHEREの最後に

B.group_id= 'grp';

とありますが、company_t_map_accounts にはデータが1件もないので、SELECT されるデータは1件もないかと。

追記
Oracle での実行結果

SQL

1SQL> SET NULL null 2SQL> SELECT 3 2 A.account_id 4 3 , C.group_account_id 5 4 FROM company_m_accounts A -- ※ Oracle ではここで AS は記述できない 6 5 LEFT OUTER JOIN company_t_map_accounts B -- ※ 7 6 ON A.company_id = B.company_id 8 7 AND A.account_id = B.group_account_id 9 8 LEFT OUTER JOIN group_m_accounts C -- ※ 10 9 ON B.group_id = C.group_id 11 10 AND A.account_id = B.group_account_id 12 11 WHERE A.company_id = 'com' 13 12 AND B.group_id = 'grp'; 14 15レコードが選択されませんでした。 16 17SQL> -- AND B.group_id = 'grp' を削ると、 18SQL> SELECT 19 2 A.account_id 20 3 , C.group_account_id 21 4 FROM company_m_accounts A 22 5 LEFT OUTER JOIN company_t_map_accounts B 23 6 ON A.company_id = B.company_id 24 7 AND A.account_id = B.group_account_id 25 8 LEFT OUTER JOIN group_m_accounts C 26 9 ON B.group_id = C.group_id 27 10 AND A.account_id = B.group_account_id 28 11 WHERE A.company_id = 'com'; 29 30ACCOUNT_ID GROUP_ACCO 31---------- ---------- 321000001 null 331000002 null 341000003 null 351100001 null 361110000 null 37 38SQL>

投稿2019/09/23 15:05

編集2019/09/23 22:10
Orlofsky

総合スコア16417

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

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

tomona

2019/09/23 15:55

その場合、想定される結果にある表のようにNULLを返して欲しいのですがそういった抽出は不可能ですか?
Orlofsky

2019/09/23 16:25

SQLは実際に実行して動作を確認します。CREATE TABLEもINSERTもあるから実行できる環境を用意して動作確認しては?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問