限制行输出

发布于 2024-12-23 06:09:30 字数 1623 浏览 3 评论 0原文

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

这是我的数据(不,这些不是正确的列名称,我试图使其更易于阅读)我从中提取的实际表有 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 记录,并且部门是 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

清晰如泥,对吗?

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

感谢您提供的任何帮助。

米歇尔

I am having some trouble figuring out the correct syntax for what I need to output from my query.

Here is my data (no these are not the correct column names, I'm trying to make it easier to read) The actual table I'm pulling from has 26 columns of data.

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

So, here are the selection rules:
If type is P select that record
If employee has no P record, select S
If employee has multiple S records, select the lower record number OR select the record that the Dept is NOT 400 (the 400 row will always be the higher record number)
If there is only one S record, and the Dept is 400 the row should be returned

This is what is currently working:

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

And what I WANT to do is put "limit = 1" (or something similar) at the end, so that in the case of multiple S rows the lower recordNumber will be the row that is returned.

This is the record set that should be returned from the data above:

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

Clear as mud, right?

I keep getting errors. Is there an "easy" way to do it that I'm just missing?

Thanks for any help you can give.

Michelle

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

审判长 2024-12-30 06:09:30

我不太理解这部分:

选择较低的记录编号或选择该部门所在的记录
NOT 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)

I don't undestood very good this part:

select the lower record number OR select the record that the Dept is
NOT 400 (the 400 row will always be the higher record number)

(If "the 400 row will always be the higher record number" then the left part of the OR is sufficient)

However, this is a point of start.(I dismissed the part after 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)
乱了心跳 2024-12-30 06:09:30

如果您的数据在EmployeeeNumber 中不能有重复的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 与此数据将给出 2 行对于员工 12。当然,如果这不应该发生,也许您会希望您的查询报告该事实。

If your data can't have duplicate TYPE and recordNumber values within an employeNumber, then @Florin's answer works. Otherwise, if there's any chance at all that your ORDER BY in the analytic function would yield two rows with the same rank, you'll get duplicate rows again. I'd use ROW_NUMBER instead, and the WHERE clause can be simplified to simply select all rows with a row number of 1 (which you could do with @Florin's query as well):

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;

Yields this:

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

Using RANK with this data would give 2 rows for employee 12. Of course, if this should not happen, perhaps you would want your query to report that fact.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文