Задать вопрос
@nurzhannogerbek

Как отфильтровать записи по ближайшей дате?

Здравствуйте! Помогите пожалуйста разобраться.

У меня есть следующая модель данных.

models.py:
class Securities(models.Model):
    section = models.ForeignKey(Section)
    characteristic = models.ForeignKey(Characteristics)
    bool_value = models.NullBooleanField()
    change_date = models.DateTimeField()
    real_change_date = models.DateTimeField()


У примеру в таблице есть такие записи:
SECTION  | CHARACTERISTIC | CHANGE_DATE | BOOL_VALUE
   A     |       8328     |  15.02.2018 |      1
   A     |       8328     |  02.09.2018 |      0
   B     |       8328     |  02.09.2018 |      1
   C     |       8328     |  02.09.2018 |      1
   C     |       8328     |  20.09.2018 |      0


Я пытаюсь отфильтровать подобную таблицу:
SECTION  | CHARACTERISTIC | CHANGE_DATE | BOOL_VALUE
   C     |       8328     |  20.09.2018 |      0
   B     |       8328     |  02.09.2018 |      1
   A     |       8328     |  02.09.2018 |      0



То есть отфильтровать записи таким образом, чтобы у похожих записей брались лишь та у которой ближайшая дата.

Я попытался сделать следующее:
securities = Securities.objects.filter(characteristic=8328).order_by('-change_date').values_list('section').distinct()


Данный код возвращается 36 записей, и записи все равно дублируются. То есть есть две записи A. Хотя нужно оставить одну. При этом когда я пишу print(securities.count()) мне пишет количество 33. Что вообще происходит. Как решить данную проблему, друзья?
  • Вопрос задан
  • 198 просмотров
Подписаться 1 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 3
half-life
@half-life
select distinct on (section)
  section,
  characteristic,
  change_date,
  bool_value
from securities
where characteristic = 8328
group by id, section
order by section desc, change_date desc



section | characteristic | change_date | bool_value
---------+----------------+----------------------------+------------
c | 8328 | 2018-09-20 12:28:00.701+00 | f
b | 8328 | 2018-09-02 12:28:00.701+00 | t
a | 8328 | 2018-09-02 12:27:41.907+00 | f
(3 rows)



ну и соответсвенно если тебе нужны только секции

select distinct on (section)
  section
from accounts_securities
where characteristic = 8328
group by id, section
order by section desc, change_date desc


ps. Блин ток щас заметил что у тебя в тегах Oracle, я под постгрисом проверял.
Ответ написан
@ponaehal
По ощущениям, спасет коррелированный подзапрос. Как то так:
SELECT * FROM securities t
WHERE t.change_date IN (SELECT Max(t1.change_date) FROM securities t1 WHERE t.section=t1.section)
Если будет долго работать, то подозреваю, что можно придумать что-нибудь более производительное с использованием аналитических функций...
Ответ написан
@x_shader
Oracle & Coffee
select
  section
 ,characteristic
 ,change_date
 ,bool_value
  from (
    select
      section
     ,characteristic
     ,change_date
     ,bool_value
     ,row_number() over (partition by section, characteristic order by change_date desc) as rn
  )
 where rn = 1


Сорри что поздно, но пусть здесь будет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы