限制行输出

时间:2011-12-29 15:15:52

标签: sql oracle limit oracle8i

我在查询输出查询所需的正确语法时遇到了一些麻烦。

这是我的数据(没有这些不是正确的列名,我试图让它更容易阅读)我从中提取的实际表有26列数据。

employeeNumber - recordNumber - job                - dept - type
 12            - 1            - stapler            - 788  - s
 12            - 6            - paper pusher       - 400  - s
 18            - 2            - phone cleaner      - 600  - p
 18            - 4            - sweeper            - 567  - s
 19            - 0            - typist             - 400  - s
 21            - 0            - mouse ball cleaner - 400  - p

所以,这是选择规则:
如果类型为P则选择该记录
如果员工没有P记录,请选择S
如果员工有多个S记录,请选择较低的记录编号或选择部门不是400的记录(400行总是是更高的记录编号)
如果只有一条S记录,而Dept为400则应返回该行

这是目前的工作:

SELECT employeeNumber, recordNumber, job, dept, type
FROM employees
WHERE (type = 'P')
 OR
 (type = 'S'
            AND employeeNumber NOT IN
                (
                  SELECT employeeNumber
                  FROM employees
                  WHERE type = 'P'
                )
)
ORDER BY employeeNumber, recordNumber

我想要做的是在结尾放置“limit = 1”(或类似的东西),这样在多个S行的情况下,较低的recordNumber将是返回的行。

这是应从上述数据返回的记录集:

employeeNumber - recordNumber - job                - dept - type
 12            - 1            - stapler            - 788  - s
 18            - 2            - phone cleaner      - 600  - p
 19            - 0            - typist             - 400  - s
 21            - 0            - mouse ball cleaner - 400  - p

清楚如泥,对吧?

我不断收到错误。是否有一种“简单”的方法可以让我失踪?

感谢您提供任何帮助。

米歇尔

2 个答案:

答案 0 :(得分:1)

这部分我并不感到非常好:

  

选择较低的记录号或选择Dept所在的记录   不是400(400行将始终是更高的记录号)

(如果“400行总是更高的记录数”,则OR的左侧部分就足够了)

然而,这是一个开始点。(我在OR之后驳回了部分)

SELECT * FROM (
    SELECT employeeNumber, recordNumber, job, dept, type
    rank() over (partition by employeeNumber order by type, recordNumber) as rnk
    FROM employees
)
WHERE type = 'P' or (rnk=1 and type=S)

答案 1 :(得分:0)

如果您的数据在employeNumber中不能有重复的TYPE和recordNumber值,那么@ Florin的答案就可以了。否则,如果分析函数中的ORDER BY有任何机会产生具有相同排名的两行,则会再次获得重复行。我改为使用ROW_NUMBER,并且可以简化WHERE子句以简单地选择行号为1的所有行(您也可以使用@Florin的查询):

CREATE TABLE employees (employeeNumber INTEGER, recordNumber INTEGER
           , job VARCHAR2(100), dept INTEGER, TYPE VARCHAR2(2));

INSERT INTO employees VALUES (12, 6, 'paper pusher', 400, 'S');
INSERT INTO employees VALUES (18, 2, 'phone cleaner', 600, 'P');
INSERT INTO employees VALUES (18, 4, 'sweeper', 567, 'S');
INSERT INTO employees VALUES (19, 0, 'typist', 400, 'S');
INSERT INTO employees VALUES (21, 0, 'mouse ball cleaner', 400, 'P');
INSERT INTO employees VALUES (12, 1, 'stapler', 788, 'S');
INSERT INTO employees VALUES (12, 1, 'stapler2', 654, 'S');

SELECT employeeNumber, recordNumber, job, dept, type
  FROM (SELECT employeeNumber, recordNumber, job, dept, type
             , ROW_NUMBER() 
                 OVER (PARTITION BY employeeNumber 
                           ORDER BY type, recordNumber) rn
          FROM employees)
 WHERE rn = 1;

产生这个:

EMPLOYEENUMBER  RECORDNUMBER JOB                   DEPT TYPE
-------------- ------------- -------------------- ----- ----
            12             1 stapler                788 S
            18             2 phone cleaner          600 P
            19             0 typist                 400 S
            21             0 mouse ball cleaner     400 P

对这些数据使用RANK会为员工12提供2行。当然,如果不应该这样做,也许您希望查询报告这一事实。