3

我在确定我需要从查询中输出的内容的正确语法时遇到了一些麻烦。

这是我的数据(不,这些不是正确的列名,我试图让它更容易阅读)我从中提取的实际表有 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 记录,选择较低的记录号或选择 Dept 不是 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

像泥一样清澈,对吧?

我不断收到错误。有没有一种我只是想念的“简单”方法?

谢谢你提供的所有帮助。

米歇尔

4

2 回答 2

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)
于 2011-12-29T15:50:06.180 回答
0

如果您的数据在employeeNumber 中不能有重复的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 行。当然,如果这不应该发生,也许您希望您的查询报告该事实。

于 2011-12-30T16:22:02.900 回答