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

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

詳細はこちら
MySQL

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

4690閲覧

Python MySQLのテーブルから取得したデータのリスト化

begginer_pygo

総合スコア16

MySQL

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

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/03/22 15:17

編集2021/03/23 08:00

Python初心者に力をお貸し下さい。

現在以下のようなMySQL(RDS)のテーブルからデータを取得し、リスト形式にしたいと思っております。
色々処理を考えていましたが、うまいやり方が浮かばず良い方法があればお教えください。

【環境】
Python3.7.6
EC2からRDSへpymysqlでデータを取りに行きます

Table:START_END_ITEM

Start_datetimeEnd_datetimeItem
2021/3/1 12:00:002021/3/1 14:00:00Apple
2021/3/1 16:00:002021/3/1 17:00:00Peach
2021/3/1 19:00:002021/3/1 22:00:00Orange

【欲しい形】
[2021/3/1 14:00:00,2021/3/1 16:00:00,Apple]
[2021/3/1 17:00:00,2021/3/1 19:00:00,Peach]

End_datetimeから次のStart_datetimeになるまでEnd_datetimeのItemを持たせたい。

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

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

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

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

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

ppaul

2021/03/23 01:09

「MySQLのテーブルからデータを取得し」というのはできているのですか?
begginer_pygo

2021/03/23 07:48

ご質問いただきありがとうございます。 以下のようなシンプルなクエリで取得してから、欲しい形に成型出来ないかと考えていました。 もしクエリを投げる時点で欲しい形でとれる方法などがあればご教示ください Select * from START_END_TIME where Start_datetime >= 2021/3/1 00:00:00
guest

回答4

0

「うまいやり方」というのは難しいですね。
データの抽出処理は基本的にRDBMS側に極力移譲したいところですが、一方でRDBMSは一般的には、各々のレコードにアクセスをする機能は弱いという特徴があるように思います。
saziさんやhoshi-takanoriの回答のとおり、SQLでなんとかする方法で今後の保守もいけそうならそれでもよいと思います。
RDBMS側が弱いと言われている各々のレコードにアクセスをする処理をPython側でやるなら、以下のような実装でどうでしょうか。

Python

1import pymysql 2# MySQLに接続する 3connection = pymysql.connect(host='localhost', 4 user='ユーザー名', 5 password='パスワード', 6 db='データベース名', 7 charset='utf8', 8 cursorclass=pymysql.cursors.DictCursor) 9# SQLを操作する 10with connection.cursor() as cursor: 11 #「my_table」から「tw_id」が重複を省いた仮テーブル「my_table_temp」を作成する 12 sql = "select * from START_END_ITEM where Start_datetime >= '2021/3/1 00:00:00' order by Start_datetime;" 13 cursor.execute(sql) 14 records = cursor.fetchall() 15 16 # 「欲しい形」のリストを作成 17 new_records = [[records[idx]['End_datetime'], records[idx+1]['Start_datetime'], records[idx]['Item']] for idx in range(len(records)-1)] 18 19# MySQLから切断する 20connection.close() 21 22# 結果表示 23for record in new_records: 24 print(record[0].strftime("%Y/%m/%d %H:%M:%S"), record[1].strftime("%Y/%m/%d %H:%M:%S"), str(record[2]))

こちらのほうがやっている処理がわかりやすくなるので、保守しやすくはなるように思います。
ただ、先に書いたとおり、Python側に極力抽出してくるデータはRDBMS側で絞り込んだほうがパフォーマンスはよいので、一概にPython側でやるのがいいとは言えません。
begginer_pygoさんの利用したいケースによって「うまいやり方」がどれかは違ってくるとは思います。

投稿2021/03/24 00:55

NGW

総合スコア48

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

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

0

ベストアンサー

fetchallすると以下のようなデータ(result)が得られると考えて、その後をpythonで処理する方法です。
日時が文字列でもDatetime型でも同じ方法で可能です。
Start_datetimeがすでに昇順に並んでいるなら、ソートの行は不要です。

出力が違っていたので回答を修正しました。

python

1import pandas as pd 2df = pd.DataFrame(result, columns = ["Start_datetime", "End_datetime", "Item"]) 3df = df.sort_values("Start_datetime") 4df2 = df.copy() 5df2["End_datetime"] = df["Start_datetime"].shift(-1) 6df2["Start_datetime"] = df["End_datetime"] 7df3 = df2.iloc[:-1,:] 8print(df3)

実行例

python

1>>> print(result) 2[('2021/3/1 12:00:00', '2021/3/1 14:00:00', 'Apple'), ('2021/3/1 16:00:00', '2021/3/1 17:00:00', 'Peach'), ('2021/3/1 19:00:00', '2021/3/1 22:00:00', 'Orange')] 3>>> import pandas as pd 4>>> df = pd.DataFrame(result, columns = ["Start_datetime", "End_datetime", "Item"]) 5>>> df = df.sort_values("Start_datetime") 6>>> df2 = df.copy() 7>>> df2["End_datetime"] = df["Start_datetime"].shift(-1) 8>>> df2["Start_datetime"] = df["End_datetime"] 9>>> df3 = df2.iloc[:-1,:] 10>>> print(df3) 11 Start_datetime End_datetime Item 120 2021/3/1 14:00:00 2021/3/1 16:00:00 Apple 131 2021/3/1 17:00:00 2021/3/1 19:00:00 Peach

投稿2021/03/23 08:48

編集2021/03/24 14:08
ppaul

総合スコア24670

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

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

begginer_pygo

2021/03/24 03:27

解答頂きありがとうございます。もう1点だけ質問させてください。 ご提示いただいた方法でdf2の内容で取得できることまでは理解できました。 一方で欲しい形として記載したものとはStart_datetimeが異なってしまっています。  【欲しい形】   [2021/3/1 14:00:00,2021/3/1 16:00:00,Apple]   [2021/3/1 17:00:00,2021/3/1 19:00:00,Peach] Start_datetimeを変える場合もshiftを使う形でしょうか?
ppaul

2021/03/24 14:08

すみません。出力をよく読んでいませんでした。 回答を修正しました。
guest

0

たぶん Python でやった方がいいとは思いますが、MySQL 8 だとこんな感じですね。

テーブル定義

sql

1create table START_END_ITEM ( 2 Start_datetime datetime, 3 End_datetime datetime, 4 Item varchar(255) 5); 6 7insert into START_END_ITEM values ('2021/3/1 12:00:00', '2021/3/1 14:00:00', 'Apple'); 8insert into START_END_ITEM values ('2021/3/1 16:00:00', '2021/3/1 17:00:00', 'Peach'); 9insert into START_END_ITEM values ('2021/3/1 19:00:00', '2021/3/1 22:00:00', 'Orange');

問い合わせ

sql

1select End_datetime, Start_datetime, Item from 2 (select @n := @n + 1 as n, End_datetime, Item from START_END_ITEM, (select @n := 1) as x) as t1, 3 (select @m := @m + 1 as m, Start_datetime from START_END_ITEM, (select @m := 0) as y) as t2 4where n = m;

結果

+---------------------+---------------------+-------+ | End_datetime | Start_datetime | Item | +---------------------+---------------------+-------+ | 2021-03-01 14:00:00 | 2021-03-01 16:00:00 | Apple | | 2021-03-01 17:00:00 | 2021-03-01 19:00:00 | Peach | +---------------------+---------------------+-------+

投稿2021/03/23 03:05

hoshi-takanori

総合スコア7899

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

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

0

MySQLのバージョンが8.0以降なら**lead()**が使えます。
MySQL 8.0 新機能 Window Function

8.0以降でなければ、模倣する事で同様なことが出来ます。
MySQLで分析関数を模倣3(後編)

SQLでの対応では無い場合は、テーブルをStart_datetime降順で読み込んで処理するとかですね。

投稿2021/03/23 03:03

sazi

総合スコア25327

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問