Выберите запрос с максимальной датой

у меня есть этот запрос

SQL-запрос: выбор по ветке и машинному коду, порядок по ветке и дате

SELECT  
    mb.machine_id AS 'MachineId',
    MAX(mb.date) AS 'Date',
    mi.branch_id AS 'BranchId',
    b.branch AS 'Branch',
    b.branch_code AS 'BranchCode'
FROM
    dbo.machine_beat mb
    LEFT JOIN dbo.machine_ids mi
    ON mb.machine_id = mi.machine_id
    LEFT JOIN dbo.branches b
    ON mi.branch_id = b.lookup_key
GROUP BY 
    mb.machine_id,
    mi.branch_id,
    b.branch,
    b.branch_code
ORDER BY 
    b.branch, [Date] DESC

Результат запроса:

|==========|=======================|=========|==========|==========|
|MachineId |Date                   |BranchId |Branch    |BranchCode|
|==========|=======================|=========|==========|==========|
|SS10000005|2014-03-31 19:10:17.110|3        |Mamamama  |MMMM      |
|SS10000043|2014-03-31 17:16:32.760|3        |Mamamama  |MMMM      |
|SS10000005|2014-02-17 14:58:42.523|3        |Mamamama  |MMMM      |
|==================================================================|

Моя проблема в том, как выбрать обновленный машинный код? Ожидаемый результат запроса:

|==========|=======================|=========|==========|==========|
|MachineId |Date                   |BranchId |Branch    |BranchCode|
|==========|=======================|=========|==========|==========|
|SS10000005|2014-03-31 19:10:17.110|3        |Mamamama  |MMMM      |
|==================================================================|

Обновление Я создал sqlfiddle. Я также добавил данные, кроме MMMM. Мне нужны обновленные date для каждой ветки. Так что, вероятно, мой результат будет:

|==========|=======================|=========|==========|==========|
|MachineId |Date                   |BranchId |Branch    |BranchCode|
|==========|=======================|=========|==========|==========|
|SS10000343|2014-06-03 13:43:40.570|1        |Cacacaca  |CCCC      |
|SS30000033|2014-03-31 18:59:42.153|8        |Fafafafa  |FFFF      |
|SS10000005|2014-03-31 19:10:17.110|3        |Mamamama  |MMMM      |
|==================================================================|

person naru    schedule 03.06.2014    source источник
comment
Какую БД вы используете?   -  person Ambrish    schedule 03.06.2014
comment
@861051069712110711711710997114 MS SQL   -  person naru    schedule 03.06.2014
comment
Проблема machineId. Чтобы лучше помочь вам, нам нужно увидеть начальные образцы данных для этих результатов.   -  person Clockwork-Muse    schedule 03.06.2014
comment
@Clockwork-Muse Я вернусь, я попытаюсь скопировать свою таблицу в sqlfiddle. Заранее спасибо!   -  person naru    schedule 03.06.2014
comment
@Clockwork-Muse Привет, смотрите мой пост с обновлением. Заранее спасибо! :)   -  person naru    schedule 03.06.2014


Ответы (2)


@861051069712110711711710997114 смотрит в правильном направлении — это самый большой n-на-группу вопрос. У вас сложнее, чем обычно, потому что часть greatest поступает из другой таблицы, чем часть group. Единственная проблема с его ответом заключается в том, что вы не предоставили достаточно информации, чтобы закончить его правильно.

Следующее решает проблему:

WITH Most_Recent_Beat AS (SELECT Machine.branch_id,
                                 Beat.machine_id, Beat.date,
                                 ROW_NUMBER() OVER(PARTITION BY Machine.branch_id 
                                                   ORDER BY Beat.date DESC) AS rn
                          FROM machine_id Machine
                          JOIN machine_beat Beat
                            ON Beat.machine_id = Machine.machine_id)
SELECT Beat.machine_id, Beat.date,
       Branches.lookup_key, Branches.branch, Branches.branch_code
FROM Branches
JOIN Most_Recent_Beat Beat
  ON Beat.branch_id = Branches.lookup_key
     AND Beat.rn = 1
ORDER BY Branches.branch, Beat.date DESC

(и исправлена ​​SQL Fiddle для тестирования. Не следует использовать другую СУБД для например, тем более, что были синтаксические ошибки для базы данных, которую вы говорите, что используете.)

Что дает ожидаемые результаты.

Так что же здесь происходит? Ключом является ROW_NUMBER()-функциональная линия. Сама эта функция просто генерирует числовой ряд. Предложение OVER(...) определяет так называемое окно, в котором будет выполняться функция. PARTITION BY сродни GROUP BY - каждый раз, когда возникает новая группа (новое значение Machine.branch_id), функция перезапускается. ORDER BY внутри круглых скобок просто говорит о том, что на группу записи должны запускать данную функцию для записей в указанном порядке. Таким образом, наибольшая дата (самая последняя, ​​при условии, что все даты в прошлом) получает 1, следующая 2 и т. д.
Здесь это делается в CTE (это также может быть сделано как часть подзапроса table-reference ), потому что требуется только самая последняя дата, где сгенерированный номер строки равен 1; поскольку SQL Server не позволяет вам помещать псевдонимы SELECT в предложение WHERE, его необходимо обернуть на другом уровне, чтобы иметь возможность ссылаться на него таким образом.

person Clockwork-Muse    schedule 03.06.2014
comment
Спасибо за подробное объяснение, хотя я не могу полностью понять его на данный момент, но позже я попытаюсь проанализировать ваш ответ шаг за шагом. Также спасибо за исправление моего sqlfiddle, я им впервые пользуюсь. На данный момент я не могу проголосовать за ваш ответ и ответ @ 861051069712110711711710997114, огромное спасибо! это действительно помогает :) - person naru; 04.06.2014
comment
ой, у меня внезапно достаточно репутации, ваш ответ и ответ @ 861051069712110711711710997114 заслуживают положительного голосования, еще раз спасибо! - person naru; 04.06.2014
comment
Хм... если вы не понимаете, мне, возможно, придется его изменить. С чем у вас проблемы? - person Clockwork-Muse; 04.06.2014
comment
Нет, нет, просто я впервые использую штуку partition by, и я запутался, как она работает и как ею пользоваться. Прочитав ваше объяснение снова и снова, выполняя ваш запрос шаг за шагом, я теперь понимаю, что вы сказали о CTE и о том, как он работает. Спасибо за дополнительные знания и хорошо объясненный ответ :) - person naru; 04.06.2014

Попробуйте использовать Row_number с partition by

     select * from 
        (
        SELECT  
            mb.machine_id AS 'MachineId',
            mb.date AS 'Date',
            mi.branch_id AS 'BranchId',
            b.branch AS 'Branch',
            b.branch_code AS 'BranchCode',rn=row_number()over(partition by mb.machine_id order by mb.date desc)
        FROM
            dbo.machine_beat mb
            LEFT JOIN dbo.machine_ids mi
            ON mb.machine_id = mi.machine_id
            LEFT JOIN dbo.branches b
            ON mi.branch_id = b.lookup_key
        WHERE 
            branch_code = 'MMMM'
/*
        GROUP BY 
            mb.machine_id,
            mi.branch_id,
            b.branch,
            b.branch_code
*/
        )x

    where x.rn=1
person vhadalgi    schedule 03.06.2014
comment
У меня ошибка в строке раздела Column 'dbo.machine_beat.date' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. - person naru; 03.06.2014
comment
попробуйте добавить mb.date в группу по? - person vhadalgi; 03.06.2014
comment
@861051069712110711711710997114 Нет необходимости добавлять mb.date в группу по - person Vignesh Kumar A; 03.06.2014
comment
@ 861051069712110711711710997114 ой, извините, я добавил mb.date в группу, но результат запроса такой же, как показано выше (3 данных) - person naru; 03.06.2014
comment
@VigneshKumar: да, я этого не видел! - person vhadalgi; 03.06.2014
comment
@ 861051069712110711711710997114 У меня тот же результат. Почему max() удалили? - person naru; 03.06.2014
comment
@naru: тебе не нужно этого делать! так как здесь вы используете сообщение row_number() ovar(date desc) в sqlfiddle с некоторым образцом - person vhadalgi; 03.06.2014
comment
@ 861051069712110711711710997114 Я вернусь, я попытаюсь скопировать свою таблицу в sqlfiddle. Заранее спасибо! - person naru; 03.06.2014
comment
@ 861051069712110711711710997114 Привет, посмотри мой пост с обновлением. Заранее спасибо! :) - person naru; 03.06.2014