Обновить самую новую строку базы данных с тем же значением столбца - PullRequest
1 голос
/ 25 мая 2020

У меня есть таблица, как показано ниже:

------------------------------------------------------
| 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     |
------------------------------------------------------

, и мне нужен статус обновления для самой новой публикации sh даты в любой группе года и периода, но я понятия не имею об этом

например:
выберите все строки для 2020 года с периодом 03, а затем обновите stauts новейшей publish_date до 1, а затем выполните ту же операцию для года 2020 с периодом 04 до конца ...
Я хочу использовать это в django поэтому, пожалуйста, объясните с помощью pythoni c way или sql query

это моя 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)  
    ...

большое спасибо

Ответы [ 3 ]

0 голосов
/ 25 мая 2020

Решение 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 здесь .

0 голосов
/ 28 мая 2020

эта работа в 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

всем спасибо

0 голосов
/ 25 мая 2020

Я не знаком с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...