我想返回按Oracle 10g中的日期排序的每组前n行
EMPLOYEE|START_DATE|DEPARTMENT
Amy |01-02-1901|Sales
Edwina |01-02-1902|Mergers
Tawnee |01-02-1904|Legal
Trudy |01-02-1998|Sales
Tanner |01-02-1967|Sales
Kelly |01-02-1954|Mergers
Jenny |01-02-1991|Sales
Jacinta |01-02-1924|Legal
Suzanne |01-02-1976|Legal
Jacqui |01-02-1989|Legal
Jill |01-02-1989|Mergers
Kate |01-02-1998|Mergers
Jane |01-02-1900|Sales
Louise |01-02-1912|Mergers
Kim |01-02-1976|Sales
Cara |01-02-1955|Sales
Kirsten |01-02-1933|Legal
Sarah |01-02-1998|Legal
EMPLOYEE|START_DATE|DEPARTMENT
Jane |01-02-1900|Sales
Amy |01-02-1901|Sales
Tawnee |01-02-1904|Legal
Jacinta |01-02-1924|Legal
Sarah |01-02-1998|Legal
Edwina |01-02-1902|Mergers
Louise |01-02-1912|Mergers
(select * from
employees where
DEPARTMENT = 'Sales' and
rownum <3;)
UNION
(select * from
employees where
DEPARTMENT = 'Legal' and
rownum <3;)
UNION
(select * from
employees where
DEPARTMENT = 'Mergers' and
rownum <3;)
非常丑陋的查询
我在想你是否有办法可以
OVER (PARTITION BY DEPARTMENT)
但是根据我的阅读,这需要在分析函数之前(计数,求和)。有没有更优雅,更便宜的解决方案?
答案 0 :(得分:2)
使用计数相关聚合查询来考虑这种非Windows函数方法。我们的想法是运行一个部门排名子查询,然后在派生表中使用它,按此部门排名过滤外部查询。请注意,您所需的结果不会按订购的START_DATE
返回,而只是查询行号。
SELECT main.EMPLOYEE, t.START_DATE, t.DEPARTMENT
FROM
(SELECT t.EMPLOYEE, t.START_DATE, t.DEPARTMENT,
(SELECT Count(*) FROM Employees sub
WHERE sub.START_DATE <= t.START_DATE
AND sub.Department = t.Department) AS DeptRank
FROM Employees t) main
WHERE main.DeptRank <= 3
ORDER BY main.DEPARTMENT, main.START_DATE;
-- EMPLOYEE START_DATE DEPARTMENT
-- Tawnee 1/2/1904 Legal
-- Jacinta 1/2/1924 Legal
-- Kirsten 1/2/1933 Legal
-- Edwina 1/2/1902 Mergers
-- Louise 1/2/1912 Mergers
-- Kelly 1/2/1954 Mergers
-- Jane 1/2/1900 Sales
-- Amy 1/2/1901 Sales
-- Cara 1/2/1955 Sales
对于Windows功能对应部分:
SELECT main.EMPLOYEE, t.START_DATE, t.DEPARTMENT
FROM
(SELECT t.EMPLOYEE, t.START_DATE, t.DEPARTMENT,
RANK() OVER (PARTITION BY Department
ORDER BY START_DATE) AS DeptRank
FROM Employees t) main
WHERE main.DeptRank <= 3
ORDER BY main.DEPARTMENT, main.START_DATE;
正如@Matt评论,您可能想要处理关系(即在同一天开始的员工)。上述两种解决方案都将根据排名过滤器输出所有此类员工。要在相关子查询中使用其中一个关系,请使用 Employee 名称作为决胜局(或者更好的是唯一ID(如果可用)):
SELECT main.EMPLOYEE, t.START_DATE, t.DEPARTMENT
FROM
(SELECT t.EMPLOYEE, t.START_DATE, t.DEPARTMENT,
(SELECT Count(*) FROM Employees sub
WHERE sub.Department = t.Department
AND (sub.START_DATE <= t.START_DATE
OR sub.START_DATE = t.START_DATE
AND sub.EMPLOYEE < t.EMPLOYEE) AS DeptRank
FROM Employees t) main
WHERE main.DeptRank <= 3
ORDER BY main.DEPARTMENT, main.START_DATE;
对于窗口函数查询,请使用ROW_NUMBER()
代替RANK()
。