SQL人员重复

时间:2013-06-15 15:55:20

标签: sql join duplicates

如何消除人员的重复。

SELECT Persons.Id, Activity.Activity, Activity.Description, Activity.StartDate, Activity.EndDate
FROM Activity
INNER JOIN Login_Activity ON Activity.ActivityId = Login_Activity.ActivityId
INNER JOIN Persons ON Login_Activity.LoginId = Persons.LoginId
AND Activity.Description IS NOT NULL ORDER BY Persons.Id DESC


Person 1 - Activity 1
Person 1 - Activity 2
Person 2 - Activity 1
Person 3 - Activity 2
Person 3 - Activity 3

编辑:我想要这个结果。

Person 1 - Activity 1
Person 2 - Activity 1
Person 3 - Activity 3

因为活动表还包含som timestables,我只想要每个活动的最后一个日期时间。对于那个问题,我只使用ORDER DESC函数。但我也需要消除重复。

EDIT2:如果我只是使用SQL查询对最大值进行排序,然后使用PHP数组仅向人员显示一次。

mainArray = array(

 'person' => '1', 'Activity' => 'abc', 

'person' => '1', 'Activity' => 'cba',

'person' => '2', 'Activity' => 'abc',

'person' => '2', 'Activity' => 'cba',

'person' => '3', 'Activity' => 'cba'

);

2 个答案:

答案 0 :(得分:0)

您需要一个中间子查询,以识别每个用户所需的最新(或其他)登录活动。假设Login_Activity有一个名为LoginActivityID的字段,它是一个整数自动增量字段,那么这将起作用:

SELECT
    P.Id, 
    A.Activity, 
    A.Description, 
    A.StartDate, 
    A.EndDate
FROM
    Persons P
            INNER JOIN
    (
        SELECT  LA2.LoginId, MAX(LA2.LoginActivityID) LoginActivityID
        FROM    Login_Activity LA2
                        INNER JOIN
                Activity A2
        WHERE   A2.Description IS NOT NULL
        GROUP BY LA2.LoginId
    ) LAX
            ON
        P.LoginId = LAX.LoginId
            INNER JOIN
    Login_Activity LA
            ON
        LAX.LoginActivityID = LA.LoginActivityID
            INNER JOIN
    Activity A
            ON
        LA.ActivityID = A.ActivityID

答案 1 :(得分:0)

您没有说出您正在使用的SQL风格 - 它对可能的内容产生了很大的影响。

现在大多数数据库都支持RANK功能,这提供了一种非常有效的解决方案。 (一个值得注意的例外是MySql - 它不支持RANK)

在CTE中,RANK()用于按降序日期顺序对每个人的所有活动进行排名。我假设你想要保持最新的一个完成,并且在一个平局的情况下,最新的一个开始,如果仍然是平局,我使用活动PK作为平局破坏者使查询确定。

外部查询只是选择CTE中排名为1的所有记录。

这可以通过单次扫描活动表来提供答案 - 没有讨厌的相关子查询来减慢速度: - )

with rankedActivities as (
 select p.Id,
        a.Activity,
        a.Description,
        a.StartDate,
        a.EndDate
        Rank() over (
          partition by p.Id
          order by a.EndDate desc, a.StartDate desc, a.ActivityId desc
        ) dateRank
   from persons p
   inner join Login_Activity la
      on la.LoginId = p.LoginId
   inner join Activity a
      on a.ActivityId = la.ActivityId
)
select Id,
       Activity,
       Description,
       StartDate,
       EndDate
  from rankedActivies
 where dateRank=1
;