Mysql: выберите самую последнюю запись по пользователю и номеру дела - PullRequest
3 голосов
/ 28 ноября 2011

У меня есть таблица, данные которой выглядят так:

INSERT INTO `cm_case_notes` (`id`, `case_id`, `date`, `time`, `description`, `username`,       `supervisor`, `datestamp`) VALUES
(45977, '1175', '2010-11-19 16:27:15', 600, 'Motion hearing...Denied.', 'bjones', 'jharvey,', '2010-11-19 21:27:15'),
(46860, '1175', '2010-12-11 16:11:19', 300, 'Semester Break Report', 'bjones', 'jharvey,', '2010-12-11 21:11:19'),
(48034, '1175', '2011-05-04 17:30:03', 300, 'test', 'bjones', 'jharvey,', '2011-05-04 22:30:03'),
(14201, '1175', '2009-02-06 00:00:00', 3600, 'In court to talk to prosecutor, re: the file', 'csmith', 'sandrews', '2009-02-07 14:33:34'),
(14484, '1175', '2009-02-13 00:00:00', 6300, 'Read transcript, note taking', 'csmith', 'sandrews', '2009-02-16 17:22:36');

Я пытаюсь выбрать самую последнюю заметку по делу (по date) для каждого случая по каждому пользователю. Лучшее, что я придумал, это:

SELECT * , MAX(  `date` ) FROM cm_case_notes WHERE case_id =  '1175' GROUP BY username

Это, однако, дает не самую последнюю запись, а первую для каждого пользователя. Я видел несколько подобных постов здесь, но я просто не могу понять их. Кто-нибудь пожалел бы о sql-дефиците и помог бы?

Ответы [ 3 ]

5 голосов
/ 28 ноября 2011

Если вам нужны только даты самой последней заметки для каждого пользователя и каждого случая, вы можете использовать это:

--- Q ---
SELECT case_id
     , username 
     , MAX(  `date` ) AS recent_date 
FROM cm_case_notes 
GROUP BY case_id
       , username 

Если вам нужны все столбцы из этой строки (с самой последней датой) перейдите по ссылке Quassnoi для различных решений (или других предоставленных ссылок).Проще всего было бы превратить указанный выше запрос в подзапрос и присоединить его к cm_case_notes:

SELECT cn.*
FROM 
      cm_case_notes AS cn
  JOIN 
      ( Q ) AS q
    ON  ( q.case_id,  q.username,  q.recent_date ) 
      = ( cn.case_id, cn.username, cn.`date` )

Если вам нужна только последняя заметка, но только для определенного case_id, затем вы можете добавить условие where в cn и Q (Q слегка изменено):

SELECT cn.*
FROM 
      cm_case_notes AS cn
  JOIN 
      ( SELECT username 
             , MAX(  `date` ) AS recent_date 
        FROM cm_case_notes 
        WHERE case_id = @particular_case_id
        GROUP BY username 
      ) AS q
    ON  ( q.username,  q.recent_date ) 
      = ( cn.username, cn.`date` )
WHERE cn.case_id = @particular_case_id
2 голосов
/ 28 ноября 2011

причина, по которой вы не получаете то, что хотели бы получить из базы данных, заключается в использовании SELECT * вместе с GROUP.

Фактически, можно безопасно выбирать только результаты агрегатных функций и / или самих групповых полей. выбор чего-либо еще приводит к неожиданным результатам. (точный результат зависит от порядка, оптимизации запросов и тому подобного).

То, что вы пытаетесь достичь, называется извлечением «группового максимума». Это распространенная проблема / распространенная задача в SQL, вы можете прочитать хорошую статью здесь: http://jan.kneschke.de/projects/mysql/groupwise-max/

или в руководстве по MySQL здесь: http://dev.mysql.com/doc/refman/5.1/en/example-maximum-column-group-row.html

или подробное подробное объяснение пользователя Quassnoi из stackoverflow: http://explainextended.com/2009/11/24/mysql-selecting-records-holding-group-wise-maximum-on-a-unique-column/

0 голосов
/ 28 ноября 2011

Рассматривали ли вы порядок DESC и просто ограничивает 1?

...