SQl Live:显示列的最小值,加上同一张表中的对应值,加上第二张表中的相关值

Posted

技术标签:

【中文标题】SQl Live:显示列的最小值,加上同一张表中的对应值,加上第二张表中的相关值【英文标题】:SQl Live: Displaying Min value of column, plus corresponding value in same table, plus related value in second table 【发布时间】:2018-10-08 17:44:46 【问题描述】:

我有两个表,DEPT 和 EMP。 EMP 有一个对应于 DEPT 中的 deptno 列的 deptno 列。我需要在 DEPT 中显示每个部门的最早(分钟)雇用日期(EMP 中的另一列)、dname(部门名称)和员工姓名(ename)

这是我到目前为止的代码,但我不确定如何修改它以显示员工的相应姓名。

SELECT dname, MIN(hiredate) AS "Most Senior"

FROM dept, emp  
WHERE dept.deptno = emp.deptno  
GROUP BY dname

编辑这里是表格:

CREATE TABLE dept(   
  deptno     number(2,0),   
  dname      varchar2(14),   
  loc        varchar2(13),   
  CONSTRAINT pk_dept PRIMARY KEY (deptno)   
);

CREATE TABLE emp(

  empno    number(4,0),   
  ename    varchar2(10),   
  job      varchar2(9),   
  mgr      number(4,0),   
  hiredate date,   
  sal      number(7,2),   
  comm     number(7,2),   
  deptno   number(2,0),   
  CONSTRAINT pk_emp PRIMARY KEY (empno),   
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept (deptno)   
);

【问题讨论】:

【参考方案1】:

如果您的 DBMS 支持,您可以使用row_number()

SELECT x.hiredate,
       x.dname,
       x.ename
       FROM (SELECT e.hiredate,
                    d.dname,
                    e.ename,
                    row_number() OVER (PARTITION BY d.deptno
                                       ORDER BY e.hiredate) rn
                    FROM dept d
                         INNER JOIN emp e
                                    ON e.deptno = d.deptno) x
       WHERE x.rn = 1;

我还建议使用显式 JOIN 语法。

【讨论】:

谢谢,感谢您的快速回答。我是 SQL 新手,对如何使用 row_number() 不太熟悉,所以我不确定这里的所有语法是什么意思。 x.hiredate、x.dname、x.ename 到底在做什么? @GoldPonyBoy:x 只是子查询的别名。所以x.<column name> 我只是引用子查询中的一列。【参考方案2】:

您可以使用相关子查询:

select d.dname, d.*
from dept d join
     emp e
     on d.deptno = e.deptno
where e.hiredate = (select min(e2.hiredate) from emp e2 where e2.deptno = e.deptno);

您也可以使用row_number()rank() 解决此问题。在许多数据库中,相关子查询通常具有更好的性能,尤其是在 e(deptno, hiredate) 上的索引时。

【讨论】:

【参考方案3】:

尝试再添加一个比较受雇日期的条件。如果你能给出表格结构和一些示例数据会更有帮助。

SELECT 
  dname,
  e.ename,
  min(e.hiredate) as hire_date 
FROM 
  dept as d, emp e 
where 
  d.deptno = e.deptno 
group by 
  d.deptno
having
  e.hiredate = hire_date

【讨论】:

我的语法有问题,这给了我一个错误,说命令没有正确结束 我在之前的查询中打错字了。我已经编辑了答案。【参考方案4】:

为了不仅选择 min(hire_date) 还选择关联的员工,您需要使用某种方法按部门内的hire_date 对员工进行排名。最简单的方法是使用 row_number 函数。使用您的示例代码:

select dept.dname , emp.hiredate as "most_senior" , emp.ename as "senior_employee" from dept join (select * , row_number(PARTITION BY deptno ORDER BY hiredate) as rn from emp ) emp on dept.deptno = emp.deptno and emp.rn = 1 ;

【讨论】:

这给了我一个错误,说“在预期的地方找不到 FROM 关键字”如果我在语法方面遗漏了一些东西,我深表歉意,我之前没有使用 row_number() 将我的代码编辑得更明确,应该可以解决问题。

以上是关于SQl Live:显示列的最小值,加上同一张表中的对应值,加上第二张表中的相关值的主要内容,如果未能解决你的问题,请参考以下文章

sql 将多行显示为一行,如果一张表中有几行数据中的同一列的值是相同,那么只显示为一行的数据

如何在sql中将同一张表中的两个值连接起来?

sql选择某一列的最大值与最小值并在同一列中显示

用 Oracle 中同一张表中的其他行数据更新一行

sql如何将一张表中的一列数据分为两列显示

在 Oracle PL/SQL 中,当列的其余值相等时,我可以交换表中两个不同行的同一列的值吗?