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

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

詳細はこちら
MySQL

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

Q&A

解決済

1回答

697閲覧

mysqlにて複数のカラムから1つのレコードを一括で抽出するクエリの作成

Yuki_T

総合スコア1

MySQL

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

0グッド

0クリップ

投稿2020/12/09 03:11

編集2020/12/09 04:19

前提・実現したいこと

mysqlにて複数のカラムから1つのレコードを一括で抽出するクエリの作成
mysqlバージョン : Ver 14.14 Distrib 5.7.25

発生している問題・エラーメッセージ

イメージ説明

期待抽出結果のように取得するクエリを作成のため、お力添えいただけると助かります。
areaテーブルのarea_cd1とarea_cd2の組み合わせごとに、keiyaku_tableから下記条件に合致する最大値のレコードを取得し、keiyaku_detail_tableのkeiyaku_ypeを取得したいです。

・抽出条件 (同一のレコードが複数存在する場合、1)→2)→3)→4)の順でチェック)

  1. 条件no1カラムの最大カラム
  2. 条件no2カラムの最大カラム
  3. 条件no3カラムの最大カラム
  4. 条件no4カラムの最大カラム

・各カラム属性
area_cd1 : VARCHAR(10)
area_cd2 : VARCHAR(10)
no1 : int
no2 : tinyint
no3 : tinyint
no4 : tinyint
keiyaku_type : VARCHAR(10)

試したこと

下記クエリで1件ずつ取得はできたのですが、抽出したいレコードが1000件近くあるため、一括で取得できればと思っています。

SELECT area_table.area_cd1,area_table.area_cd2,keiyaku_detail_table.no1,keiyaku_detail_table.no2,keiyaku_detail_table.no3,keiyaku_detail_table.no4,keiyaku_detail_table.keiyaku_type FROM keiyaku_detail_table INNER JOIN keiyaku_no_table ON ( keiyaku_detail_table.no1 = keiyaku_no_table.no1 AND keiyaku_detail_table.no2 = keiyaku_no_table.no2 AND keiyaku_detail_table.no3 = keiyaku_no_table.no3 AND keiyaku_detail_table.no4 = keiyaku_no_table.no4) WHERE (area_table.area_cd1 = '10' AND area_table.area_cd2 = '100') ORDER BY keiyaku_detail_table.no1 DESC, keiyaku_detail_table.no2 DESC, keiyaku_detail_table.no3 DESC, keiyaku_detail_table.no4 DESC LIMIT 1;

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

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

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

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

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

K_Y_M

2020/12/09 03:44

期待抽出結果3行目のレコードは 20 100 3300 2 1 1 M ではなく 20 100 3300 1 1 1 M なのでしょうか?
sazi

2020/12/09 04:08 編集

MySQLのバージョンは何ですか?質問に追記して下さい。
sazi

2020/12/09 04:14

それから、no1~no4の属性は何ですか? no1~no4を文字列として結合したものをソートしても希望する並びになりますか?
Yuki_T

2020/12/09 04:21

K_Y_M 様 ご指摘恐れ入ります、ご指摘通りですので修正させていただきました。 sazi 様 バージョンと属性を追記させていただきました。 > no1~no4を文字列として結合したものをソートしても希望する並びになりますか? はい、希望する並びとなります
guest

回答1

0

ベストアンサー

keiyaku_detail_tableから最大値のキーを取得するSQLを考えてみます。
マルチカラムなので項目ごとに順次求めようとすると、それぞれをネストした集計する相関サブクエリーが必要です。
一塊のカラムに纏めるとネストが不要になるので、先ずはパフォーマンスは考慮せずにこの方針でSQLを組み立てると以下の様になります。

SQL

1select no1 2 , cast(substring_index(substring_index(concat_no, '-', 1), '_', -1) as tinyint) as no2 3 , cast(substring_index(substring_index(concat_no, '-', 2), '_', -1) as tinyint) as no3 4 , cast(substring_index(substring_index(concat_no, '-', 3), '_', -1) as tinyint) as no4 5from ( 6 select no1 7 , max(concat( 8 lpad(cast(no2 as char), 3, '0') 9 , '-', lpad(cast(no3 as char), 3, '0') 10 , '-' ,lpad(cast(no4 as char), 3, '0') 11 )) as concat_no 12 from keiyaku_detail_table 13 group by no1 14 ) valid_key

解説:
1.na2~3を桁を揃えて結合し、no1に対する最大を求めます。※後で分解する為-で繋ぎます。
2.join用に結合した文字列をsubstring_index()を使用して分解し属性を変換します。
追記

桁が固定にでき、文字位置で判断できるので、単純に結合した方がシンプルでしたので訂正。

SQL

1select no1 2 , cast(substring(concat_no, 1, 3) as tinyint) as no2 3 , cast(substring(concat_no, 4, 3) as tinyint) as no3 4 , cast(substring(concat_no, 7, 3) as tinyint) as no4 5from ( 6 select no1 7 , max(concat( 8 lpad(cast(no2 as char), 3, '0'), lpad(cast(no3 as char), 3, '0'),lpad(cast(no4 as char), 3, '0') 9 )) as concat_no 10 from keiyaku_detail_table 11 group by no1 12 ) valid_key

上記を使用して以下の様なSQLになります。
※手打ちで動作検証はしていませんので、悪しからず。

SQL

1select area.area_cd1, area.area_cd2 2 , dtl.no1, dtl.no2, dtl.no3, dtl.no4, dtl.keiyaku_type 3from area_table area 4 inner join keiyaku_no_table kyk 5 on kyk.area_cd1 = area.area_cd1 6 and kyk.area_cd2 = area.area_cd2 7 inner join keiyaku_detail_table dtl 8 on dtl.no1 = kyk.no1 9 and dtl.no2 = kyk.no2 10 and dtl.no3 = kyk.no3 11 and dtl.no4 = kyk.no4 12 inner join ( 13 select no1 14 , cast(substring(concat_no, 1, 3) as tinyint) as no2 15 , cast(substring(concat_no, 4, 3) as tinyint) as no3 16 , cast(substring(concat_no, 7, 3) as tinyint) as no4 17 from ( 18 select no1 19 , max(concat( 20 lpad(cast(no2 as char), 3, '0'), lpad(cast(no3 as char), 3, '0'),lpad(cast(no4 as char), 3, '0') 21 )) as concat_no 22 from keiyaku_detail_table 23 group by no1 24 ) valid_key 25 ) valid_key 26 on valid_key.no1 = dtl.no1 27 and valid_key.no2 = dtl.no2 28 and valid_key.no3 = dtl.no3 29 and valid_key.no4 = dtl.no4 30where area.area_cd1 = '10' 31 and area.area_cd2 = '100'

投稿2020/12/09 05:11

編集2020/12/09 05:30
sazi

総合スコア25327

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問