Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
返回每个组的前n条记录Oracle SQL 我的问题_Sql_Oracle_Syntax - Fatal编程技术网

返回每个组的前n条记录Oracle SQL 我的问题

返回每个组的前n条记录Oracle SQL 我的问题,sql,oracle,syntax,Sql,Oracle,Syntax,我想返回Oracle 10g中按日期排序的每组前n行 我的桌子 预期结果 我试过的 但从我读到的,这之前需要一个分析函数count,sum,随便什么。是否有更优雅、更便宜的解决方案?考虑使用计数相关聚合查询的非Windows函数方法。其思想是运行部门级别子查询,然后在派生表中使用该子查询,该派生表按此部门级别筛选外部查询。请注意,您所需的结果不是按顺序开始日期返回,而是按查询的行号返回 SELECT main.EMPLOYEE, t.START_DATE, t.DEPARTMENT FROM

我想返回Oracle 10g中按日期排序的每组前n行

我的桌子 预期结果 我试过的
但从我读到的,这之前需要一个分析函数count,sum,随便什么。是否有更优雅、更便宜的解决方案?

考虑使用计数相关聚合查询的非Windows函数方法。其思想是运行部门级别子查询,然后在派生表中使用该子查询,该派生表按此部门级别筛选外部查询。请注意,您所需的结果不是按顺序开始日期返回,而是按查询的行号返回

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所说,您可能希望处理关系,即当天开始工作的员工。上述两种解决方案都将根据等级过滤器输出所有此类员工。要获取相关子查询中的一个联系,请使用员工姓名作为联系断开者,或者最好使用唯一的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;

对于窗口函数查询,请使用行编号代替秩。

您在正确的轨道上。看看上面评论中提到的Nir Levy的帖子。看看你是否能根据你的情况调整解决方案——这是正确的方法。如果您的数据中可能存在关联,则会有一些细微的变化——如果没有关联,您应该可以继续。如果解决方案不起作用,请再次写信解释您在哪里发现困难,或者您的案例与旧案例相比有什么不同。祝你好运因为OP特别指出top n不是top n与TIES,所以最好注意,非窗口函数将包括TIES,窗口函数也包括TIES,但OP可以将秩更改为ROW_编号以消除TIES。很好的一点,Matt。我把这种情况扩大到你的信用!
OVER (PARTITION BY DEPARTMENT)
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
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;
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;