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

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

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

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

Q&A

解決済

4回答

1802閲覧

SQL 副問い合わせ

merci_children

総合スコア44

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

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

0グッド

0クリップ

投稿2020/03/05 01:39

編集2020/03/06 01:43

以下のSQLでこのような期待値を取りたいのですが、うまく取れません。
解決方法を教えていただけると嬉しいです。

【結果】
"TESTGY01";2;"業務宛名担当者(管理者)_old";"ギョウムタントウシャ(カンリシャ)オールド"
"TESTGY01";2;"業務宛名担当者(管理者)";"ギョウムタントウシャ(カンリシャ)"

【期待値】
"TESTGY01";2;"業務宛名担当者(管理者)";"ギョウムタントウシャ(カンリシャ)"

【データ】
〇USER_AUTH
"TESTGY01";2;
"TESTGY02";1;

〇USER_NAME
"TESTGY01";1;"業務宛名担当者(管理者)_old";"ギョウムタントウシャ(カンリシャ)オールド";
"TESTGY01";2;"業務宛名担当者(管理者)";"ギョウムタントウシャ(カンリシャ)";

SELECT UA.USER_ID AS "USER_ID" , UA.RIREKI_NUMBER AS "RIREKI_NUMBER" , UN.USER_NAME_KANJI AS "USER_NAME_KANJI" , UN.USER_NAME_KANA AS "USER_NAME_KANA" FROM USER_AUTH UA LEFT JOIN USER_NAME UN ON UA.USER_ID = UN.USER_ID WHERE NOT EXISTS ( SELECT * FROM USER_AUTH B WHERE UA.USER_ID = B.USER_ID AND UA.RIREKI_NUMBER < B.RIREKI_NUMBER ) AND UA.USER_ID = 'TESTGY01'

【補足】
試してみたSQLは以下です。

SELECT UA.USER_ID AS "USER_ID" , UA.RIREKI_NUMBER AS "RIREKI_NUMBER" , UN.USER_NAME_KANJI AS "USER_NAME_KANJI" , UN.USER_NAME_KANA AS "USER_NAME_KANA" FROM USER_AUTH UA LEFT JOIN ( SELECT UN.USER_ID AS "USER_ID" , UN.RIREKI_NUMBER AS "RIREKI_NUMBER" , UN.USER_NAME_KANJI AS "USER_NAME_KANJI" , UN.USER_NAME_KANA AS "USER_NAME_KANA" FROM USER_NAME B WHERE UN.USER_ID = B.USER_ID AND UN.RIREKI_NUMBER < B.RIREKI_NUMBER ) USER_NAME UN ON UA.USER_ID = UN.USER_ID WHERE NOT EXISTS ( SELECT * FROM USER_AUTH B WHERE UA.USER_ID = B.USER_ID AND UA.RIREKI_NUMBER < B.RIREKI_NUMBER ) AND UA.USER_ID = 'TESTGY01'

追加
CREATE TABLE user_auth
(
user_id character varying(30) NOT NULL,
rireki_number integer NOT NULL DEFAULT 1,
CONSTRAINT pk_user_auth PRIMARY KEY (user_id, rireki_number)
)

CREATE TABLE user_name
(
user_id character varying(30) NOT NULL,
rireki_number integer NOT NULL DEFAULT 1,
user_name_kanji character varying(205),
user_name_kana character varying(205),
CONSTRAINT pk_user_name PRIMARY KEY (user_id, rireki_number)
)

〇USER_AUTH
INSERT INTO user_auth (user_id, rireki_number) VALUES ('TESTGY01', 1);
INSERT INTO user_auth (user_id, rireki_number) VALUES ('TESTGY02', 2);

〇USER_NAME
INSERT INTO user_name (user_id, rireki_number,user_name_kanji,user_name_kana) VALUES ('TESTGY01', 1,"業務宛名担当者(管理者)_old",ギョウムタントウシャ(カンリシャ)オールド);
INSERT INTO user_name (user_id, rireki_number,user_name_kanji,user_name_kana) VALUES ('TESTGY01', 2,"業務宛名担当者(管理者)",ギョウムタントウシャ(カンリシャ));

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

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

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

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

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

m.ts10806

2020/03/05 01:47

各テーブルのCREATEとサンプルデータのINSERTもご提示ください
Orlofsky

2020/03/05 01:49

SQLで使われるテーブルはCREATE TABLEされていなければなりません。テーブル内のデータはINSERTされていなければSELECTできません。ですから、質問にCREATE TABLEやINSERTでデータを提示した方が適切な回答が付き易いです。
merci_children

2020/03/05 10:01

失礼しました。 明日クリエイトテーブルとサンプルデータのインサートをあげさせていただきます。
merci_children

2020/03/06 01:44

追加しました。恐れ入りますがよろしくお願いいたします。
guest

回答4

0

ベストアンサー

結合条件にUA.RIREKI_NUMBER = UN.RIREKI_NUMBERを加えるだけです。
Existsの条件は不要です
USER_AUTH のプライマリーが(USER_ID, RIREKI_NUMBER )なので訂正。

SQL

1SELECT UA.USER_ID, UA.RIREKI_NUMBER, UN.USER_NAME_KANJI, UN.USER_NAME_KANA 2FROM USER_AUTH UA 3 LEFT JOIN USER_NAME UN 4 ON UA.USER_ID = UN.USER_ID 5 AND UA.RIREKI_NUMBER = UN.RIREKI_NUMBER 6WHERE UA.USER_ID = 'TESTGY01' 7 and not exists( 8 select 1 from USER_AUTH 9 where USER_ID=UA.USER_ID 10 and RIREKI_NUMBER > UA.RIREKI_NUMBER 11 ) 12

※"を使用した項目名やエイリアスは大文字小文字を厳密に区別されるようになります。
意識しての事なら良いですけど、そうでないなら"は使用しない方が良いかと思います。

追記

RIREKI_NUMBERがそれぞれのテーブルごとのものの場合(最新のUSER_AUTHと最新のUSER_NAMEを結合したい)
は、not existsを同様に条件として追加すればOK

SQL

1SELECT UA.USER_ID, UA.RIREKI_NUMBER, UN.USER_NAME_KANJI, UN.USER_NAME_KANA 2FROM USER_AUTH UA 3 LEFT JOIN ( 4 select * 5 from USER_NAME UN 6 where not exists( 7 select 1 from USER_NAME 8 where USER_ID=UN.USER_ID and RIREKI_NUMBER > UN.RIREKI_NUMBER 9 ) 10 ) UN 11 ON UA.USER_ID = UN.USER_ID 12WHERE UA.USER_ID = 'TESTGY01' 13 and not exists( 14 select 1 from USER_AUTH 15 where USER_ID=UA.USER_ID and RIREKI_NUMBER > UA.RIREKI_NUMBER 16 )

投稿2020/03/07 06:53

編集2020/03/07 07:32
sazi

総合スコア25327

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

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

merci_children

2020/03/15 07:57

遅くなってしまい、申し訳ございません。 回答ありがとうございます。追記のSQLを試した結果うまくいきました。
guest

0

SELECT
auth.user_id as id,
last.rireki_number as rireki_no,
name.user_name_kanji as kanji,
name.user_name_kana as kana
FROM
user_auth as auth
INNER JOIN
user_name as name
ON auth.user_id = name.user_id,
(
SELECT
MAX(user_name.rireki_number) as rireki_number
FROM
user_name
) as last
WHERE
name.rireki_number = last.rireki_number
AND auth.user_id = 'TESTGY01'


上記の質問を踏まえて考えると以下のとおりであると想定しています。

user_authのuser_idに紐付いているuser_nameの最大履歴番号を取得したい。

->
user_nameの履歴番号は増える。
user_auth.rireki_numberは別の要件で使うかで今回は考慮しない。

思考手順としては、user_nameの最大履歴番号を取得してその値で絞り込むことで導出できるのではと考えました。

実行手順としては、
user_nameの最大履歴番号を取得するのに、MAX関数を利用しました。

https://www.postgresql.jp/document/11/html/tutorial-agg.html

  • 利用されているversionをご確認ください。

初心者マークが付与されていることを鑑みて、ASは省略していません。

投稿2020/03/07 03:24

onesword0618

総合スコア19

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

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

0

sql

1SELECT 2 * 3FROM 4 USER_AUTH AS UA 5 LEFT JOIN 6 (SELECT USER_ID, MAX(RIREKI_NUMBER) AS 'RIREKI_NUMBER' FROM USER_NAME GROUP BY USER_ID) AS UN 7 ON UA.USER_ID = UN.USER_ID AND UA.RIREKI_NUMBER = UN.RIREKI_NUMBER 8 LEFT JOIN 9 USER_NAME AS UN2 10 ON UN.USER_ID = UN2.USER_ID AND UN.RIREKI_NUMBER = UN2.RIREKI_NUMBER 11WHERE 12 UA.USER_ID = 'TESTGY01'

投稿2020/03/05 02:01

mongolia

総合スコア133

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

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

merci_children

2020/03/05 10:31

ちょっと時間をください。 SQLが不慣れなもので、理解するのに時間がかかってます。。。
guest

0

単純に結合条件に履歴Noをいれてやればいいです。

sql

1SELECT 2 UA.USER_ID AS "USER_ID" 3 , UA.RIREKI_NUMBER AS "RIREKI_NUMBER" 4 , UN.USER_NAME_KANJI AS "USER_NAME_KANJI" 5 , UN.USER_NAME_KANA AS "USER_NAME_KANA" 6FROM 7 USER_AUTH UA 8 LEFT JOIN 9 USER_NAME UN 10 ON UA.USER_ID = UN.USER_ID 11 AND UA.RIREKI_NUMBER = UN.RIREKI_NUMBER // ←これを追加 12WHERE 13 NOT EXISTS ( 14 SELECT 15 B.USER_ID 16 FROM 17 USER_AUTH B 18 WHERE 19 UA.USER_ID = B.USER_ID 20 AND UA.RIREKI_NUMBER < B.RIREKI_NUMBER 21 ) 22 AND UA.USER_ID = 'TESTGY01'

投稿2020/03/05 01:50

macaron_xxx

総合スコア3191

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

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

merci_children

2020/03/05 10:30

これだとUSER_NAMEの履歴Noが3とかの場合にとってこれなくなっちゃいます。。。
sazi

2020/03/07 07:02

not exists 部分は不要だと思いますけど、「履歴Noが3」が追加されると、USER_AUTHのRIREKI_NUMBERも3になるのではないですか? そうでないなら、USER_AUTHのRIREKI_NUMBERは何を管理するのでしょうか?
sazi

2020/03/07 07:17

USER_AUTHのRIREKI_NUMBERもプライマリーの一部なんですね・・・ そうなるとテーブルを分ける意味が不明ですけど
macaron_xxx

2020/03/09 02:46

このテーブル構成からRIREKI_NOがそれぞれのテーブルで独立しているとは思いませんでした。
macaron_xxx

2020/03/09 02:48

NOT EXISTS をいれいるのは、もちろん履歴Noなんだから、最新のものを取る必要があると思っただけですね。 そうでないなら、履歴Noの意味…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問