我返回并返回这个问题和答案。不幸的是,在某些情况下,使用“排名窗口函数”进行迁移变得非常复杂。这些情况是:
- Oracle查询的select部分中基于不同顺序的许多KEEP-DENSE_RANK结构
- 通过分组集/汇总分组
因此,我将在答案中添加其他信息。原始数据SQLFIDDLE:http ://sqlfiddle.com/#!6/e5c6d/6
1.读取oracle函数:
select max(m.id), m.someId keep (DENSE_RANK FIRST ORDER BY m.UpdateDate desc)
from MyTable m
groupBy m.someId
在那里我们选择组中最大的 m.id (someId, UpdateDate) 其中 UpdateDate 是组中最大的 (someId)
2.由于错误,直接方式不起作用:列“MyTable.UpdateDate”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable
GROUP BY someId
3.改进的“直截了当”是无效的
SELECT someId, MIN(first_in_orderedset)
FROM
( SELECT FIRST_VALUE(id) OVER(PARTITION BY someId ORDER BY UpdateDate DESC, id DESC) first_in_orderedset , someId
FROM MyTable ) t
GROUP BY someId;
4.交叉申请:
SELECT grouped.someId, orderedSet.FirstUpdateDate, maxInSet.first_in_orderedset FROM
(
SELECT mt.someId
FROM MyTable mt
GROUP BY mt.someId
) grouped CROSS APPLY
(
SELECT top 1 mt2.UpdateDate as FirstUpdateDate
FROM MyTable mt2
WHERE mt2.someId=grouped.someId
ORDER BY UpdateDate desc
) orderedSet CROSS APPLY
(
SELECT max(mt3.id) as first_in_orderedset
FROM MyTable mt3
WHERE mt3.someId=grouped.someId and mt3.UpdateDate=orderedSet.FirstUpdateDate
) maxInSet;
5.现在让我们获取更复杂的表和更复杂的查询: ORACLE : http://sqlfiddle.com/#!4/c943c/23
SQL SERVER: http://sqlfiddle.com/#!6/dc7fb/1/ 0
(数据是预先生成的,在两个沙箱中是相同的 - 很容易比较结果)表:
CREATE TABLE AlarmReports (
id int PRIMARY KEY,
clientId int, businessAreaId int , projectId int, taskId int,
process1Spent int, process1Lag int, process1AlarmRate varchar2(1) null,
process2Spent int, process2Lag int, process2AlarmRate varchar2(1) null,
process3Spent int, process3Lag int, process3AlarmRate varchar2(1) null
)
甲骨文查询:
SELECT clientId, businessAreaId, projectId,
sum(process1Spent),
sum(process2Spent),
sum(process3Spent),
MIN(process1AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process1Lag DESC),
MIN(process2AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process2Lag DESC),
MIN(process3AlarmRate) KEEP (DENSE_RANK FIRST ORDER BY process3Lag DESC)
FROM AlarmReports
GROUP BY GROUPING SETS ((),(clientId),(clientId, projectId),(businessAreaId),(clientId,businessAreaId))
SQL查询:
(to be continued)
实际上,我已经计划将我的自定义聚合用 c# 编写。如果有人有兴趣,请与我联系...自定义聚合是此类问题的最佳解决方案,但就 varchar 长度而言,它并不是 unviersal。对于每个 varchar 长度,您将有义务创建“专业”聚合函数