显示每个员工的不同记录

时间:2012-01-24 01:20:14

标签: mysql distinct

我有两张桌子预约app和faculty fac。它们是具有相同empid的多个记录

  1. 我需要通过app.employeeid=fac.empid加入两个表格(这里我会得到重复的记录)
  2. app.begindate<=now and app.enddate>=now and app.percent>.50(这里我也会获得重复记录,因为empid(具有相同ID的多个记录)可以具有相同的begindate,结束日期和&gt; .50)
  3. max(app.amt)(这里我也会得到重复的记录,因为empid(具有相同id的多个记录)可能有相同的amt)。最后,我想选择distinct(max(app.amt))来获得empid的单个记录。
  4. 我使用了查询:

    select max(app.amt) ,fac.email,fac.employee_id,fac.empid,fac.first_name,fac.last_name,fac.department_id,fac.titlecode,app.begindate,app.enddate,app.percent,
    app.title_name,app.department_name from faculty fac, appointment app where 
    app.employeeid=fac.empid and app.begindate <= now() and app.enddate >= now() and app.percent>.50  group by fac.empid
    /
    

    我遇到问题我得到max(app.amt)但是相应的列值与max amt record没有正确匹配。其他列值是随机的。我希望显示确切的相应值。

    约会表中的样本日期为几个文件:

    SELECT app.amt, fac.email, fac.employee_id, fac.empid, 
                     fac.first_name, fac.last_name, fac.department_id, fac.titlecode,
                     app.begindate, app.enddate, app.percent,
                     app.title_name, app.department_name 
    FROM appointment app
    LEFT JOIN appointment app2                                    -- self-join to locate  max
    ON app.employee_id = app2.employee_id AND app.amt < app2.amt --  of app.amt
    INNER JOIN faculty fac ON app.employee_id=fac.empid           -- join to fac
    WHERE app2.amt IS NULL                                        -- isolate rows with     max(app.amt)
    AND app.begindate <= NOW() 
    AND app.enddate >= NOW() 
    AND app.percent>.50 group by fac.empid
    
    
    employee_id begindate enddate     amt        percent  department_name
    5528        7/1/2011  9/30/2011   0          1        m1
    5528        7/1/2011  9/30/2011   193100     1        m1
    5528        10/1/2011 6/30/2013   79000      1        m1
    5528        10/1/2011 6/30/2013   118500     1        m2
    5528        10/1/2011 6/30/2013   0          1        m2
    

1 个答案:

答案 0 :(得分:1)

对于每个employee_id,不仅要选择MAX(列)而且选择与其对应的行,通常使用LEFT JOIN将表连接到自身。 (这也称为“每组最大n个”,并且在此标记下的stackoverflow中存在许多问题)。

e.g。选择max(app.amt)每employee_id 及其相应的行

SELECT app.*
FROM appointment app
LEFT JOIN appointment app2
 ON app.employee_id = app2.employee_id AND app.amt < app2.amt
WHERE app2.amt IS NULL;

为什么这样做?从本质上讲,这表示“为每位员工选择amt对该员工没有更高amt的行”。

LEFT JOIN appointment app2 ON app.employee_id=app2.employee_id app加入employee_id GROUP BY(请注意这是您想要的appointment)。这会生成一个amt表,每个employee_id都有app.amt < app2.amt(app.amt,app2.amt)

然后,我们还指定LEFT JOIN。因此,我们只显示app.amt对前者小于后者的行。 由于这是app2,如果我们碰巧找到app2.amt,我们找不到app2.amt中相应的一行,其中相同的employee_id和更大 app.amt,然后将LEFT JOIN设置为NULL。当我们为该员工找到最大 SELECT app.amt, fac.email, fac.employee_id, fac.empid, fac.first_name, fac.last_name, fac.department_id, fac.titlecode, app.begindate, app.enddate, app.percent, app.title_name, app.department_name FROM appointment app LEFT JOIN appointment app2 -- self-join to locate max ON app.employee_id = app2.employee_id AND app.amt < app2.amt -- of app.amt INNER JOIN faculty fac ON app.employee_id=fac.empid -- join to fac WHERE app2.amt IS NULL -- isolate rows with max(app.amt) AND app.begindate <= NOW() AND app.enddate >= NOW() AND app.percent>.50 时,正好

解决方案

因此,使用此“LEFT JOIN appointment app2 ... WHERE app2.amt IS NULL自行调整查询以获取相应的行”方法:

app.amt

所以,唯一改变的是:

  • 添加employeeid以找到每个FROM app, fac .. WHERE app.employeeid=fac.empid的最大JOIN行。
  • 将您的GROUP BY更改为MAX(app.amt)(请参阅下面的说明)
  • 无需INNER JOINFROM app, fac ... WHERE join_condition - FROM app LEFT JOIN fac ON join_condition负责处理此事。

关于将WHERE转换为app的注意事项:从多个表中选择并加入fac,联接往往更有效。

您使用哪种类型的加入(INNER JOINapp)可能会对您的结果产生影响;恢复以前的行为使用fac。这将仅显示员工存在于 LEFT JOIN INNER JOIN表中的行。

使用NULL效率略高于fac.xxx,结果将相同除非您的约会表中有一名员工没有条目在教师表中。然后,它们将显示在结果列表中,并RIGHT JOIN显示所有NULL字段。

使用{{1}}将显示教师表中的每位员工,无论他们是否有约会 - 如果他们没有约会,他们仍会在结果中显示,只需{{1}}他们所有与预约相关的领域。

JOIN中的细微差别(啊,但这是另一个问题)。