Как отсортировать по двум полям? - PullRequest
4 голосов
/ 21 января 2011

У меня есть проблема с сортировкой / группировкой, которая, я надеюсь, кто-нибудь может добавить для понимания.

У нас есть таблица историй с датой публикации и обновленной датой.Я использую Django, так что это выглядит так:

class Story(models.Model):
    pub_date = models.DateTimeField(db_index=True)
    update_date = models.DateTimeField(blank=True, null=True, db_index=True)
    headline = models.CharField(max_length=200)
    ...

Мы хотим отобразить истории на страничной странице, сгруппированной по дням.Итак ...

Jan 20
    Story 1
    Story 2

Jan 19
    Story 1
    Story 3

Проблема в том, что если у истории есть дата обновления, она должна отображаться дважды, один раз в день публикации и один раз в дату обновления (например, история 1).

Есть десятки тысяч историй, поэтому я, конечно, не могу сделать все это на python, но я не знаю, как выполнить этот запрос в SQL.

Что у меня есть сейчассортирует все по -pub_date, а затем получает диапазон максимальных и минимальных дат на данной странице.Затем я запрашиваю любые истории между этими датами с update_date и объединяю и группирую их в python.Проблема в том, что количество элементов на странице нерегулярно.

Поэтому я предполагаю, что мой вопрос заключается в следующем: как лучше всего запросить таблицу для списка элементов и отсортировать их по двум полям, дублируя элемент в запросе, если он имеет значение во второмполе, а затем сортировка на основе двух полей?

Надеюсь, что имеет смысл ...

Ответы [ 3 ]

3 голосов
/ 21 января 2011

Я могу думать только о том, что «союз» может это сделать.

вот пример того, как это будет выглядеть. не уверен, насколько быстро или хорошо для базы данных часто отправлять запросы такого типа, хотя D:

запрос предполагает, что имя вашей таблицы историй и использует столбцы заголовок , pub_date и update_date также предполагается, что история, которая не была обновлена, имеет значение null в столбце update_date.

SELECT      headline,
            the_date,
            DAY(the_date) AS the_day
FROM (
    SELECT      headline,
                pub_date AS the_date
    FROM        stories
    UNION
    SELECT      headline,
                update_date AS the_date
    FROM        stories
    WHERE       update_date IS NOT NULL
) AS publishedandupdated
ORDER BY    the_date DESC;

если вы хотите добавить ограничение к запросу, это должно быть сделано последним, после предложения "order by".

0 голосов
/ 21 января 2011

Делая некоторые предположения об именах столбцов, вам нужно UNION ALL , чтобы сохранить дубликаты из обеих частей.

    select headline, actualdate=pub_date
    from story
    where pub_date between /mindate/ and /maxdate/
union all
    select headline, actualdate=update_date
    from story
    where update_date between /mindate/ and /maxdate/
order by actualdate
  • Виртуальное поле actualdate используется для сопоставления pub_date / update_date как одного столбца, для которого ORDER BY.
  • ORDER BY в выражении union-ed применяется ПОСЛЕ объединения, поэтому он должен появиться только один раз.
  • фильтр для диапазона дат применяется в пределах каждой части объединения, чтобы уменьшить размер рабочего стола (не нужно без необходимости извлекать все данные перед применением фильтра)
0 голосов
/ 21 января 2011

твой вопрос похож на тот, который у меня был. Я читал некоторые статьи со стен Facebook. У меня было две даты: одна при создании элемента (пользователь отправляет элемент), другая при поиске элемента (я прочитал элемент из Facebook) Я хотел показать элементы, которые опубликованы или получены сегодня.

SELECT link,time FROM homeWallItems WHERE 
DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= created 
OR
DATE_SUB(CURDATE(),INTERVAL 1 DAY)<= time
group by time LIMIT 0,30

Редактировать: я был слишком оптимистичен в этом предложении: это неправильно.

в этом коде вместо CURDATE (), если вы используете time, то должно работать вы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...