1

我有这个查询

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

2 回答 2

2

尝试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
于 2014-06-03T08:49:59.343 回答
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。您不应该在示例中使用不同的 RDBMS,尤其是当您说您正在使用的数据库存在语法错误时。)

这会产生您的预期结果。

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

于 2014-06-03T12:34:29.953 回答