列出拥有最老员工的经理姓名

时间:2017-03-17 01:38:56

标签: sql oracle

我正在尝试选择一名经理的姓名谁拥有最年长的员工,但是我遇到了一些问题,因为无论何时我运行这个:

SELECT PERSONAL_DETAILS.FIRST_NAME, PERSONAL_DETAILS.SURNAME, MIN(STAFF.join_date) AS Join_Date
FROM STAFF

INNER JOIN PERSONAL_DETAILS
ON STAFF.PERSONAL_ID = PERSONAL_DETAILS.PERSONAL_ID

WHERE STAFF.ROLE_NAME = 'staff'
GROUP BY PERSONAL_DETAILS.FIRST_NAME, PERSONAL_DETAILS.SURNAME

因为where子句设置为查找所有工作人员,所以返回所有工作人员,如果我要将其更改为manager,则返回所有管理员。我明白为什么会这样,但我真的不确定如何在这里解决我的问题。

我想要它所以结果集返回管理者的姓名以及他们最老的员工的日期。

我觉得它不是关于我的表是如何设置的,因为我无法在我的情况下更改它们,更多的是如何编写一个SQL语句,这将允许我选择/匹配一个名称与涉及多个表时最早的日期,因为我需要将staff表连接到personal_details,例如获取管理员的名字和姓氏,但我需要这些名称与最旧的日期匹配。例如。

3 个答案:

答案 0 :(得分:2)

让我们尝试逐步建立起来。首先 - 您似乎正在寻找公司雇用时间最长的一个或多个人,而不是最年长的员工。我的基础是您使用MIN(JOIN_DATE)来确定要选择的员工,而不是例如MIN(BIRTH_DATE)。所以,好的 - 找到最早的JOIN_DATE我们使用MIN函数,就像你已经完成的那样:

SELECT MIN(JOIN_DATE)
  FROM STAFF
  WHERE ROLE_NAME = 'staff'

很好,这让我们最早的所有"工作人员"人(而不是"经理和#34;人)。现在要找到那个JOIN_DATE的人,我们使用上面的子查询:

SELECT *
  FROM STAFF emp
  WHERE ROLE_NAME = 'staff' AND
        JOIN_DATE = (SELECT MIN(JOIN_DATE)
                       FROM STAFF
                       WHERE ROLE_NAME = 'staff')

好的,现在我们已经和公司一起工作的员工时间最长了。现在,为了找到他们的经理(根据您的评论),我们使用STAFF的BRANCH_ID找到经理:

SELECT *
  FROM STAFF mgr
  WHERE mgr.ROLE_NAME = 'manager' AND
        mgr.BRANCH_ID IN (SELECT DISTINCT BRANCH_ID
                            FROM STAFF emp
                            WHERE ROLE_NAME = 'staff' AND
                                  JOIN_DATE = (SELECT MIN(JOIN_DATE)
                                                 FROM STAFF
                                                 WHERE ROLE_NAME = 'staff')

现在我们必须访问PERSONAL_DETAILS表以查找经理的姓名,因此我们将PERSONAL_DETAILS加入上述查询

SELECT pd.FIRST_NAME, pd.SURNAME
  FROM STAFF mgr
  INNER JOIN PERSONAL_DETAILS pd
    ON pd.PERSONAL_ID = mgr.PERSONAL_ID
  WHERE mgr.ROLE_NAME = 'manager' AND
        mgr.BRANCH_ID IN (SELECT DISTINCT BRANCH_ID
                            FROM STAFF emp
                            WHERE ROLE_NAME = 'staff' AND
                                  JOIN_DATE = (SELECT MIN(JOIN_DATE)
                                                 FROM STAFF
                                                 WHERE ROLE_NAME = 'staff')

修改

现在,坦率地说,所有这些子查询都会给我带来荨麻疹和气体,使我的手部因为所有的缩进而感到疼痛,所以让我们介绍一些新的东西:Common Table Expression(CTE)。在 SELECT之前定义了一个CTE,它基本上是一个小表,你可以像主查询中的任何其他表一样使用它:

WITH MIN_STAFF_JOIN_DATE AS (SELECT MIN(JOIN_DATE) AS MIN_JOIN_DATE
                               FROM STAFF
                               WHERE ROLE_NAME = 'staff'),
     EARLIEST_EMPLOYEES AS (SELECT s.*, d.FIRST_NAME, d.SURNAME
                              FROM STAFF s
                              INNER JOIN PERSONAL_DETAILS d
                                ON d.PERSONAL_ID = s.PERSONAL_ID
                              INNER JOIN MIN_STAFF_JOIN_DATE msjd
                                ON msjd.MIN_JOIN_DATE = s.JOIN_DATE
                              WHERE s.ROLE_NAME = 'staff'),
     MANAGERS AS (SELECT m.*, d.FIRST_NAME, d.SURNAME
                    FROM STAFF m
                    INNER JOIN PERSONAL_DETAILS d
                      ON d.PERSONAL_ID = m.PERSONAL_ID
                    WHERE m.ROLE_NAME = 'manager')
SELECT ee.FIRST_NAME AS EMPLOYEE_FIRST_NAME,
       ee.SURNAME AS EMPLOYEE_SURNAME,
       ee.JOIN_DATE,
       mgr.FIRST_NAME AS MANAGER_FIRST_NAME,
       mgr.SURNAME AS MANAGER_SURNAME
  FROM EARLIEST_EMPLOYEES ee
  INNER JOIN MANAGERS mgr
    ON mgr.BRANCH_ID = ee.BRANCH_ID

答案 1 :(得分:0)

这里不需要聚合。考虑using System.Drawing; using System.Drawing.Imaging; using System.Runtime.InteropServices; namespace FastImageTest { class FastImage { private const int BytesPerPixel = 4; private readonly byte[] _buffer; private readonly int _width; private readonly int _height; private const int ExtraSpace = 0;// 1024 * 1024 * 256; public FastImage(Bitmap from) { _width = from.Width; _height = from.Height; _buffer = new byte[_width * _height * BytesPerPixel + ExtraSpace]; GCHandle handle = GCHandle.Alloc(_buffer); try { var address = Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0); var bitsPerPixel = 32; var stride = bitsPerPixel * _width; var pixelFormat = PixelFormat.Format32bppArgb; //***** Access violation occurs on next line using (var fastBitmap = new Bitmap(_width, _height, stride, pixelFormat, address)) { using (var fastBitmapGraphics = Graphics.FromImage(fastBitmap)) fastBitmapGraphics.DrawImageUnscaled(from, 0, 0); } } finally { handle.Free(); } } } class Program { static void Main(string[] args) { var original = new Bitmap(@"d:\pic.jpg"); var fast = new FastImage(original); } } } order by

fetch first 1 row only

(这适用于Oracle 12c +。在早期版本中,您需要一个子查询。)

表明了这一点,我怀疑它能做到你想要的。我希望这是SELECT pd.FIRST_NAME, pd.SURNAME, s.join_date FROM STAFF s INNER JOIN PERSONAL_DETAILS pd ON s.PERSONAL_ID = pd.PERSONAL_ID WHERE s.ROLE_NAME = 'staff' ORDER BY s.join_date FETCH FIRST 1 ROW ONLY; 人的名字,而不是他们的经理。你可以想出那个。

答案 2 :(得分:0)

试试这个

SELECT P.FIRST_NAME, P.SURNAME, X.join_date AS Join_Date
FROM PERSONAL_DETAILS P
INNER JOIN 
(SELECT STAFF.PERSONAL_ID,STAFF.JOIN_DATE FROM STAFF WHERE STAFF.ROLE_NAME = 'STAFF' AND JOIN_DATE = (SELECT MIN(JOIN_DATE) FROM STAFF WHERE STAFF.ROLE_NAME = 'STAFF')
) X On X.PERSONAL_ID = P.PERSONAL_ID

第1步:获取最低加入日期
第2步:从第1步获取员工详细信息 第3步:从第2步获取经理详细信息