选择具有最大日期的查询

时间:2014-06-03 08:39:17

标签: sql sql-server select-query

我有这个查询

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

2 个答案:

答案 0 :(得分:2)

尝试将Row_numberpartition 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

答案 1 :(得分:1)

@ 861051069712110711711710997114正朝着正确的方向前进 - 这是一个问题。你的比较复杂,因为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 for testing。您不应该使用不同的RDBMS作为示例,尤其是因为您说您正在使用的数据库存在语法错误。)

这会产生您的预期结果。

那么这里发生了什么?关键是ROW_NUMBER() - 功能线。该函数本身只生成一个数字序列。 OVER(...)子句定义了什么称为窗口,用于运行该函数。 PARTITION BY类似于GROUP BY - 每次发生新组(新Machine.branch_id值)时,该函数都会重新启动。括号内的ORDER BY只是说,每组,条目应该按照该顺序对条目运行给定的函数。因此,最大的日期(最近一次,假设所有日期都在过去)得到1,下一个2等。 这是在CTE中完成的(它也可以作为子查询表引用的一部分完成),因为只需要最近的日期 - 生成的行号为1;由于SQL Server不允许您将SELECT - 子句别名放入WHERE子句中,因此需要将其包装在另一个级别中以便能够以这种方式引用它。