SQLAlchemyはPythonからRDBMSにアクセスする際に使われる人気のライブラリです。特にSQLAlchemyのORMは感覚的にSQLクエリを発行できるので便利です。
このページでは、SQLAlchemy ORMのクエリ生成(Query)で最大値・最小値を取得する方法を解説しています。
- 最大値、最小値を取得する func.max(), func.min()
- 最大値、最小値を含む行を取得するサブクエリ
なお、複数の列で条件を指定する方法はこちらの記事で解説しています。
ORMクエリの結果をDataFrame(Pandas)で扱う方法はこちらの記事。
結論
SQLのMAX()関数, MIN()関数は、func.max()
, func.min()
が対応する。
rec: Product = session.query(
func.max(Product.price).label('price_max')
).one_or_none()
Pythonのスキルを使って毎月の収入源を増やすのが最適なんじゃないかという件
実際、今のスキルに合わせて仕事を獲得し、スキマ時間で毎月+5、+20、+70万円くらいの人が多いです。
必要なスキル、仕事の獲得までの流れは以下の記事で徹底解説しています。
(もちろん全部無料です)
空いた時間にぜひ参考にしてみてください。
実行環境
$ python --version
Python 3.9.2
$ pip freeze
pandas==1.2.3
PyMySQL==1.0.2
SQLAlchemy==1.4.5
MySQL 5.7.35
今回使用するサンプルデータ
今回使用するサンプルデータは野菜の名前と価格のセットというシンプルなもの。
class Product(Base):
__tablename__ = 'products'
id = Column(BigInteger, primary_key=True, autoincrement=True, nullable=False)
price = Column(mysql.INTEGER(unsigned=True), nullable=False)
name = Column(mysql.TEXT(), nullable=False)
import pandas as pd
q = session.query(Product)
df = pd.read_sql(q.statement, session.bind)
df.set_index('id', inplace=True)
print(df)
# price name
# id
# 1 209 キャベツ
# 2 638 レタス
# 3 426 ばれいしょ
# 4 280 たまねぎ
# 5 923 トマト
# 6 379 にんじん
# 7 310 はくさい
# 8 208 だいこん
最大値・最小値を取得
sqlalchemy.sqlモジュールの func
メンバを用いて関数functionsを指定します。
具体的には、最大値を求めるMAX()関数は func.max()
、最小値を求めるMIN()関数は func.min()
で表現できます。
また、functions.label()
関数で、エイリアス(別名)を付けることが可能。
from sqlalchemy.sql import func
rec: Product = session.query(
func.max(Product.price).label('price_max')
).one_or_none()
print(f"最高値: {rec.price_max}")
# 最も高い野菜: 923
rec: Product = session.query(
func.min(Product.price).label('price_min')
).one_or_none()
print(f"最安値: {rec.price_min}")
# 最も安い野菜: 208
最大値・最小値を含む行をサブクエリで取得
最高価格、最小価格の野菜の名前はどのように取得すればいいでしょうか?
SQLを記述するのと同様に、最大値・最小値を含む行はサブクエリを利用して取得します。
SQLAlchemyではサブクエリは Query.subquery()
で作成することができます。サブクエリを条件に指定するときは Subquery.c
メンバでカラムを指定しあmす。
最大の価格を持つ野菜の名前 Product.name
は次のように取得します。
q = session.query(
func.max(Product.price).label('price_max')
).subquery('sub1')
rec = session.query(Product).filter(
Product.price == q.c.price_max
).all()
for r in rec:
print(f"{r.name}: {r.price}")
今回参考にしたページ・資料
Column Elements and Expressions — SQLAlchemy 1.4 Documentation