简体   繁体   English

选择具有最大日期的查询

[英]Select query with max date

I have this query 我有这个问题

SQL query: selecting by branch and machine code, order by branch and date 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

Query result: 查询结果:

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

My problem is how to select the updated machine code? 我的问题是如何选择更新的机器代码? Expected query result: 预期的查询结果:

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

Update I created sqlfiddle . 更新我创建了sqlfiddle I also added data, aside from MMMM . MMMM外,我还添加了数据。 I need the updated date for each branch. 我需要每个分支的更新date So probably, my result will be: 所以可能,我的结果将是:

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

Try using Row_number with partition by 尝试使用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

@861051069712110711711710997114 is looking in the right direction - this is a question. @ 861051069712110711711710997114正在寻找正确的方向 - 这是一个问题。 Yours is more complicated than the usual because the greatest portion is coming from a different table than the group portion. 你的比较平常更复杂,因为greatest部分来自与group部分不同的表格。 The only issue with his answer is that you hadn't provided sufficient information to finish it correctly. 他的回答唯一的问题是你没有提供足够的信息来正确完成它。

The following solves the problem: 以下解决了这个问题:

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

(and corrected SQL Fiddle for testing . You shouldn't be using a different RDBMS for the example, especially as there were syntax errors for the db you say you're using.) (并更正了SQL Fiddle进行测试 。您不应该为该示例使用不同的RDBMS,尤其是因为您说您正在使用的数据库存在语法错误。)

Which yields your expected results. 这会产生您的预期结果。

So what's going on here? 那么这里发生了什么? The key is the ROW_NUMBER() -function line. 关键是ROW_NUMBER()函数行。 This function itself simply generates a number series. 该函数本身只生成一个数字序列。 The OVER(...) clause defines what's known as a window , over which the function will be run. OVER(...)子句定义了所谓的窗口 ,在该窗口上运行该函数。 PARTITION BY is akin to GROUP BY - every time a new group occurs (new Machine.branch_id value), the function restarts. PARTITION BY类似于GROUP BY - 每次出现一个新组(新的Machine.branch_id值)时,该函数都会重新启动。 The ORDER BY inside the parenthesis simply says that, per group , entries should have the given function run on entries in that order. 括号内的ORDER BY只是说每个组的条目应该按照该顺序对条目运行给定的函数。 So, the greatest date (most recent, assuming all dates are in the past) gets 1 , the next 2 , etc. 所以,最大的日期(最近的,假设所有日期都在过去)得到1 ,接下来的2 ,等等。
This is done in a CTE here (it could also be done as part of a subquery table-reference) because only the most recent date is required - where the generated row number is 1 ; 这是在CTE中完成的(它也可以作为子查询表引用的一部分完成),因为只需要最近的日期 - 生成的行号为1 ; as SQL Server doesn't allow you to put SELECT -clause aliases into the WHERE clause, it needs to be wrapped in another level to be able to reference it that way. 由于SQL Server不允许您将SELECT -clause别名放入WHERE子句中,因此需要将其包装在另一个级别中以便能够以这种方式引用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM