python – 如何将这个复杂的SQL转换为Django模型查询?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – 如何将这个复杂的SQL转换为Django模型查询?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4842字,纯文字阅读大概需要7分钟。
内容图文
![python – 如何将这个复杂的SQL转换为Django模型查询?](/upload/InfoBanner/zyjiaocheng/889/ef75061e5db9402daf93a027a194fb3d.jpg)
我正在编写一个Python / Django应用程序来进行一些库存分析.
我有两个非常简单的模型,如下所示:
class Stock(models.Model):
symbol = models.CharField(db_index=True, max_length=5, null=False, editable=False, unique=True)
class StockHistory(models.Model):
stock = models.ForeignKey(Stock, related_name='StockHistory_stock', editable=False)
trading_date = models.DateField(db_index=True, null=False, editable=False)
close = models.DecimalField(max_digits=12, db_index=True, decimal_places=5, null=False, editable=False)
class Meta:
unique_together = ('stock', 'trading_date')
这是我填充的虚拟数据:
import datetime
a = Stock.objects.create(symbol='A')
b = Stock.objects.create(symbol='B')
c = Stock.objects.create(symbol='C')
d = Stock.objects.create(symbol='D')
StockHistory.objects.create(trading_date=datetime.date(2018,1,1), close=200, stock=a)
StockHistory.objects.create(trading_date=datetime.date(2018,1,2), close=150, stock=a)
StockHistory.objects.create(trading_date=datetime.date(2018,1,3), close=120, stock=a)
StockHistory.objects.create(trading_date=datetime.date(2018,4,28), close=105, stock=a)
StockHistory.objects.create(trading_date=datetime.date(2018,5,3), close=105, stock=a)
StockHistory.objects.create(trading_date=datetime.date(2017,5,2), close=400, stock=b)
StockHistory.objects.create(trading_date=datetime.date(2017,11,11), close=200, stock=b)
StockHistory.objects.create(trading_date=datetime.date(2017,11,12), close=300, stock=b)
StockHistory.objects.create(trading_date=datetime.date(2017,11,13), close=400, stock=b)
StockHistory.objects.create(trading_date=datetime.date(2017,11,14), close=500, stock=b)
StockHistory.objects.create(trading_date=datetime.date(2018,4,28), close=105, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,4,29), close=106, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,4,30), close=107, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,5,1), close=108, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,5,2), close=109, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,5,3), close=110, stock=c)
StockHistory.objects.create(trading_date=datetime.date(2018,5,4), close=90, stock=c)
我想找到过去一周内年度低点的所有股票.
但是为了使这个问题更简单,只要假设我想找到自“2017-05-04”发生在“2018-04-30”之后或之后的最低点的所有股票.下面是我写的SQL来找到它.有用.
但是我需要帮助找出要写的Django Query以获得与此SQL相同的结果.我该怎么做?
mysql> select
-> s.symbol,
-> sh.trading_date,
-> low_table.low
-> from
-> (
-> select
-> stock_id,
-> min(close) as low
-> from
-> stocks_stockhistory
-> where
-> trading_date >= '2017-05-04'
-> group by
-> stock_id
-> ) as low_table,
-> stocks_stockhistory as sh,
-> stocks_stock as s
-> where
-> sh.stock_id = low_table.stock_id
-> and sh.stock_id = s.id
-> and sh.close = low_table.low
-> and sh.trading_date >= '2018-04-30'
-> order by
-> s.symbol asc;
+--------+--------------+-----------+
| symbol | trading_date | low |
+--------+--------------+-----------+
| A | 2018-05-03 | 105.00000 |
| C | 2018-05-04 | 90.00000 |
+--------+--------------+-----------+
2 rows in set (0.02 sec)
解决方法:
编辑:我设法使用Django子查询改革解决方案.
我们可以使用Django的aggregates with SubQuery expressions将查询翻译成Django ORM:
>创建子查询以检索每个符号的最低关闭:
from django.db.models import OuterRef, Subquery, Min
lows = StockHistory.objects.filter(
stock=OuterRef('stock'),
trading_date__gte='2017-05-04'
).values('stock__symbol')
.annotate(low=Min('close'))
.filter(trading_date__gte='2018-04-30')
>细分:
>过滤查询集以仅获取具有trading_date> =’2017-05-04’的股票.
>“GROUP BY”stock__symbol(在Djnago中分组的例子:GROUP BY ... MIN/MAX,GROUP BY ... COUNT/SUM).
>为每个元素注释最低(低)价格.
>再次过滤查询集以仅获取在trading_date> =’2018-04-30’上发生低字段的对象.
>中级结果:
虽然我们无法在此阶段获得结果,但子查询将如下所示:
[
{'stock__symbol': 'A', 'low': Decimal('105.00000')},
{'stock__symbol': 'C', 'low': Decimal('90.00000')}
]
我们错过了trading_date.
>利用子查询检索特定的StockHistory对象:
StockHistory.objects.filter(
stock__symbol=Subquery(lows.values('stock__symbol')),
close=Subquery(lows.values('low')),
trading_date__gte='2018-04-30'
).values('stock__symbol', 'trading_date', 'close')
.order_by('stock__symbol')
>细分:
> lows.values(‘stock__symbol’)和lows.values(‘low’)从子查询中检索相应的值.
>根据lows子查询值过滤查询集.同时过滤指定日期,以消除在该日期之前发生的低收盘价.
>获取指定的值.
>按stock__symbol排序结果(默认为升序).
>结果:
[
{
'close': Decimal('105.00000'),
'trading_date': datetime.date(2018, 5, 3),
'stock__symbol': 'A'
},
{
'close': Decimal('90.00000'),
'trading_date': datetime.date(2018, 5, 4),
'stock__symbol': 'C'
}
]
内容总结
以上是互联网集市为您收集整理的python – 如何将这个复杂的SQL转换为Django模型查询?全部内容,希望文章能够帮你解决python – 如何将这个复杂的SQL转换为Django模型查询?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。