Python 使用相同的列值更新数据库的最新行
我有一张如下表:Python 使用相同的列值更新数据库的最新行,python,sql,django,Python,Sql,Django,我有一张如下表: ------------------------------------------------------ | year | period | publish_date | status | -----------|-------------|---------------|-----------| | 2020 | 03 | datetime_obj | 0 | | 2020 | 03
------------------------------------------------------
| year | period | publish_date | status |
-----------|-------------|---------------|-----------|
| 2020 | 03 | datetime_obj | 0 |
| 2020 | 03 | ... | 0 |
| 2020 | 03 | ... | 0 |
| 2020 | 03 | ... | 0 |
| 2020 | 04 | ... | 0 |
| 2020 | 04 | ... | 0 |
------------------------------------------------------
我想在任何年份和期间组中更新最新发布日期的状态,但对此我没有任何想法
例如:选择2020年期间为03的所有行,然后将最新发布日期的stauts更新为1,然后对2020年期间为04的行执行相同的操作,直到结束…
我想在django中使用它,所以请用pythonic方式或sql查询进行解释 这是我的django型号:
class Balance_Sheet(models.Model):
...
publish_date = models.DateTimeField(auto_now=True)
year = models.IntegerField(null=True)
period = models.IntegerField(null=True)
status = models.IntegerField(default=0)
...
非常感谢我不熟悉django,但是它的sql看起来是这样的。因为你们已经有了资产负债表。您只需要更新部分
WITH balance_sheet(id ,yearmonth , publish_date, status)
AS (SELECT 1, '202003', '2020-03-10' , 0 UNION
SELECT 2, '202003', '2020-03-15' , 0 UNION
SELECT 3, '202004', '2020-04-20' , 0 UNION
SELECT 4, '202004', '2020-04-25' , 0
)
UPDATE b
SET status = 1
FROM balance_sheet b
JOIN (Select *,RANK() OVER (partition by yearmonth ORDER BY publish_date desc) AS rnk
from balance_sheet bal) b_latest ON b.id = b_latest.id
WHERE b_latest.rnk = 1
我不熟悉django,但是它的sql应该是这样的。因为你们已经有了资产负债表。您只需要更新部分
WITH balance_sheet(id ,yearmonth , publish_date, status)
AS (SELECT 1, '202003', '2020-03-10' , 0 UNION
SELECT 2, '202003', '2020-03-15' , 0 UNION
SELECT 3, '202004', '2020-04-20' , 0 UNION
SELECT 4, '202004', '2020-04-25' , 0
)
UPDATE b
SET status = 1
FROM balance_sheet b
JOIN (Select *,RANK() OVER (partition by yearmonth ORDER BY publish_date desc) AS rnk
from balance_sheet bal) b_latest ON b.id = b_latest.id
WHERE b_latest.rnk = 1
解决方案1 一个简单的解决方法是应用过滤器在年/月内迭代:
years = {sheet.year for sheet in Balance_Sheet.objects.all()}
for year in years:
year_months = {sheet.month for sheet in Balance_Sheet.objects.filter(year=year)}
for month in year_months:
object_to_update = Balance_Sheet.objects.filter(
year=year,
period=month
).order_by('-publish_date').first()
object_to_update.status = 1
object_to_update.save()
可能会有更复杂的ORM函数将其转换为单个查询,但我在那里编写的代码(未经测试)将在大多数/所有Django版本中运行。此外,对数据库的查询量不会很大,因为我们讨论的是年/月数量
解决方案2
在postgres数据库中,您可以尝试以下操作:
Balance_Sheet.objects.all().order_by(
'year', 'period', '-publish_date'
).distinct(
'year', 'period'
).update(
status=1
)
请注意,这在其他数据库(如MySQL)中不起作用。请参阅django文档。解决方案1 一个简单的解决方法是应用过滤器在年/月内迭代:
years = {sheet.year for sheet in Balance_Sheet.objects.all()}
for year in years:
year_months = {sheet.month for sheet in Balance_Sheet.objects.filter(year=year)}
for month in year_months:
object_to_update = Balance_Sheet.objects.filter(
year=year,
period=month
).order_by('-publish_date').first()
object_to_update.status = 1
object_to_update.save()
可能会有更复杂的ORM函数将其转换为单个查询,但我在那里编写的代码(未经测试)将在大多数/所有Django版本中运行。此外,对数据库的查询量不会很大,因为我们讨论的是年/月数量
解决方案2
在postgres数据库中,您可以尝试以下操作:
Balance_Sheet.objects.all().order_by(
'year', 'period', '-publish_date'
).distinct(
'year', 'period'
).update(
status=1
)
请注意,这在其他数据库(如MySQL)中不起作用。请参阅django文档。这是mysql中的工作
UPDATE Balance_Sheet b
INNER JOIN (SELECT max(publish_date) LastDate, year, period FROM bs GROUP BY year, period) C
ON C.LastDate = b.publish_date and C.period = b.period and C.year = b.year
SET b.status = 1
where C.LastDate = b.publish_date and C.period = b.period and C.year = b.year
感谢mysql中的所有工作
UPDATE Balance_Sheet b
INNER JOIN (SELECT max(publish_date) LastDate, year, period FROM bs GROUP BY year, period) C
ON C.LastDate = b.publish_date and C.period = b.period and C.year = b.year
SET b.status = 1
where C.LastDate = b.publish_date and C.period = b.period and C.year = b.year
谢谢大家此表的django模型在哪里?@roganjosh我在说明中添加了我的django模型此表的django模型在哪里?@roganjosh我在说明中添加了我的django模型,但这可能是一个大问题。只是我的测试数据是52000行@DanialEshghi您使用的是哪个django版本和数据库?这些东西在mysql和postgresql之间可能会发生变化。@DanialEshghi您想要执行的操作听起来像是一个维护操作。比如说,每天运行一次我编写的代码并没有问题。假设你有50年或100年的出版物,在最坏的情况下,每年会运行13个查询。如果您必须经常运行此操作,则可以方便地重构系统,以便在条件满足时自动更新状态字段。是的,数据库可能会改变一切。在出现这个问题之前,我认为每个sql数据库都是相似的,但有了这个问题,我知道它们之间存在着多少差异。谢谢你关于第二条评论:这个操作每小时运行一次,我还有一个外键列
ref\u id
属于大约1000行。这52000行仅适用于1ref\u id
和10年。实际上,我的数据约为30年或更长。是的,但这可能是一个大问题。只是我的测试数据是52000行@DanialEshghi您使用的是哪个django版本和数据库?这些东西在mysql和postgresql之间可能会发生变化。@DanialEshghi您想要执行的操作听起来像是一个维护操作。比如说,每天运行一次我编写的代码并没有问题。假设你有50年或100年的出版物,在最坏的情况下,每年会运行13个查询。如果您必须经常运行此操作,则可以方便地重构系统,以便在条件满足时自动更新状态字段。是的,数据库可能会改变一切。在出现这个问题之前,我认为每个sql数据库都是相似的,但有了这个问题,我知道它们之间存在着多少差异。谢谢你关于第二条评论:这个操作每小时运行一次,我还有一个外键列ref\u id
属于大约1000行。这52000行仅用于1ref\u id
和10年,实际上,我的数据大约是30年甚至更长