我有这个查询
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 |
|==================================================================|
答案 0 :(得分: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
答案 1 :(得分:1)
@ 861051069712110711711710997114正朝着正确的方向前进 - 这是一个greatest-n-per-group问题。你的比较复杂,因为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
子句中,因此需要将其包装在另一个级别中以便能够以这种方式引用它。