You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

连接EMPLOYEE与BOOKS表后,如何用rownum获取正确员工数据及计数

问题:使用ROWNUM限制图书行时,如何正确获取关联员工数据及计数?

现有表结构及初始化数据

建表和插入数据的SQL语句如下:

CREATE TABLE EMPLOYEE
(
    "EMPLOYEE_ID" NUMBER(19,0) NOT NULL,
    "NAME" VARCHAR2(256),
    CONSTRAINT "ID_PK" PRIMARY KEY ("EMPLOYEE_ID") ENABLE
);

CREATE TABLE BOOKS
(
    "ID" VARCHAR2(32) NOT NULL ENABLE,
    "BOOKNAME" VARCHAR2(256),
    "EMP_ID" NUMBER(19,0) NOT NULL,
    CONSTRAINT "BOOK_ID_PK" PRIMARY KEY ("ID") ENABLE,
    CONSTRAINT "EMP_FK1" FOREIGN KEY (EMP_ID) REFERENCES EMPLOYEE
);

INSERT INTO EMPLOYEE VALUES (1, 'James');
INSERT INTO EMPLOYEE VALUES (2, 'John');

INSERT INTO BOOKS VALUES (1, 'JAVA', 1);
INSERT INTO BOOKS VALUES (2, 'CProgramming', 1);
INSERT INTO BOOKS VALUES (3, 'JSP', 1);
INSERT INTO BOOKS VALUES (4, 'Accountancy', 2);
INSERT INTO BOOKS VALUES (5, 'History', 2);
INSERT INTO BOOKS VALUES (6, 'Geography', 2);

问题描述

由于BOOKS表数据量较大,希望通过rownum限制加载的图书行数,但执行以下查询无法得到正确的员工数据及计数:

SELECT DISTINCT b.EMP_ID FROM EMPLOYEE e , Books b
WHERE e.EMPLOYEE_ID= b.EMP_ID
AND rownum <= 2;

SELECT COUNT(DISTINCT b.EMP_ID) FROM EMPLOYEE e , Books b
WHERE e.EMPLOYEE_ID= b.EMP_ID
AND rownum <= 2;

期望输出所有关联的员工ID:

EMP_ID
----------
         1
         2

解决方案

问题核心是rownum的执行时机:它会在生成结果集的每一行时立即进行判断,而非先去重再限制。直接添加rownum <=2会只返回前2条关联行(均属于EMP_ID=1的员工),自然无法获取EMP_ID=2的数据。

要实现需求,需先确保获取所有关联员工,同时减少BOOKS表的扫描量,可采用以下两种思路:

思路1:通过EXISTS子查询确认员工关联关系

如果仅需获取所有有图书的员工ID,无需扫描所有图书行,只需确认员工是否存在关联图书即可:

SELECT e.EMPLOYEE_ID AS EMP_ID
FROM EMPLOYEE e
WHERE EXISTS (
    SELECT 1 FROM BOOKS b 
    WHERE b.EMP_ID = e.EMPLOYEE_ID
);

思路2:先对BOOKS表去重得到员工ID,再处理

若必须用rownum限制图书扫描行数(比如需基于图书条件过滤),可先对BOOKS表去重得到所有关联EMP_ID,再进行后续操作:

-- 获取所有关联员工ID
SELECT DISTINCT emp_id AS EMP_ID
FROM (
    SELECT b.EMP_ID 
    FROM BOOKS b
    -- 这里的rownum值只要覆盖所有员工对应的至少一行即可,比如用员工总数作为上限
    WHERE rownum <= (SELECT COUNT(DISTINCT EMP_ID) FROM BOOKS)
);

-- 获取关联员工的计数
SELECT COUNT(*) AS EMP_COUNT
FROM (
    SELECT DISTINCT b.EMP_ID
    FROM BOOKS b
);

关键提示

  • rownum是Oracle对结果行的实时编号,在查询生成结果行时立即生效,因此先加rownum限制会截断结果集,导致去重后只能得到截断范围内的员工。
  • 正确逻辑是先获取所有关联员工ID(通过去重或EXISTS子查询),再按需处理,既避免扫描过多图书行,又能得到完整的员工数据。

内容的提问来源于stack exchange,提问作者user2354566

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 13:35:37