SQL Server通过内部连接三个或更多表来选择不同的最新值

时间:2016-05-25 10:12:40

标签: mysql sql sql-server

在我的数据库中,我有这些表,每个表中都有近200,000行。

用户表:

╔════════╦══════╦═════════════╗
║ UserID ║ Name ║    Email    ║
╠════════╬══════╬═════════════╣
║   1    ║ ABC  ║ abc@abc.com ║
║   2    ║ DEF  ║ def@def.com ║
║   3    ║ XYZ  ║ xyz@xyz.com ║
╚════════╩══════╩═════════════╝

空缺表:

╔════════════╦═════════════╗
║ VacancyId  ║ VacancyName ║
╠════════════╬═════════════╣
║     1      ║  Vacancy 1  ║
║     2      ║  Vacancy 2  ║
║     3      ║  Vacancy 3  ║
╚════════════╩═════════════╝

空缺申请表:

╔══════════════════════╦═══════════╦══════════════╦══════════════════╗
║ VacancyApplicationID ║ VacancyId ║   UserID     ║ Application Date ║
╠══════════════════════╬═══════════╬══════════════╬══════════════════╣
║           1          ║     1     ║      1       ║   2009-01-01     ║
║           2          ║     1     ║      2       ║   2009-01-02     ║
║           3          ║     2     ║      1       ║   2010-01-02     ║
║           4          ║     3     ║      1       ║   2011-02-02     ║
║           5          ║     2     ║      2       ║   2010-03-04     ║
║           6          ║     1     ║      3       ║   2009-04-07     ║
╚══════════════════════╩═══════════╩══════════════╩══════════════════╝

我正在尝试将一些数据组合在一起。我想在一个网格中获取不同的用户ID及其最新应用的空缺,如下所示:

预期结果:

╔════════╦══════╦═════════════╦══════════════════════╗
║ UserID ║ Name ║    Email    ║ Last applied vacancy ║
╠════════╬══════╬═════════════╬══════════════════════╣
║   1    ║ ABC  ║ abc@abc.com ║      Vacancy 3       ║
║   2    ║ DEF  ║ def@def.com ║      Vacancy 2       ║
║   3    ║ XYZ  ║ xyz@xyz.com ║      Vacancy 1       ║
╚════════╩══════╩═════════════╩══════════════════════╝

现在有些用户没有申请任何空缺。对他们来说,我只想把" N / A"在最后申请的空缺专栏中。我怎么能这样做?

我尝试过使用下面的SQL语句,但它复制了相同的用户ID数据:

SELECT DISTINCT
    c.[id],
    va.[candidateid],
    va.[vacancyid] 
FROM user C 
INNER JOIN VacancyApplication VA ON c.userid=va.userid
ORDER BY va.application_date DESC

4 个答案:

答案 0 :(得分:1)

你走了。

   SELECT
  U.UserID,
  U.Name,
  U.Email,
  V.VacancyName
FROM User AS U
LEFT JOIN
(
SELECT
     UserID,
     MAX(ApplicationDate) AS MaxApplicationDate
FROM vacancyapplication AS VA
GROUP BY UserID
) AS MaxApp
ON U.UserID=VA.UserID
LEFT JOIN vacancyapplication AS VA
ON MaxApp.UserID=VA.UserID
AND MaxApp.MaxApplicationDate=VA.ApplicationDate
LEFT JOIN Vacancy AS V
ON VA.VacancyID=V.VacancyID

答案 1 :(得分:1)

尝试以下查询。它包括空缺申请表上的子查询,以限制每个用户的最新空缺。此外,如果给定用户没有任何应用程序,它会在申请日期使用COALESCE()

SELECT u.UserID, u.Name, u.Email, COALESCE(v.VacancyName, 'NA') AS `Last applied vacancy`
FROM User u
LEFT JOIN
(
    SELECT UserID, MAX(ApplicationDate) AS maxDate
    FROM vacancy_application
    GROUP BY UserID
) v1
    ON u.UserID = v1.UserID
LEFT JOIN vacancy_application v2
    ON u.UserID = v2.UserID AND v2.ApplicationDate = v1.maxDate
LEFT JOIN Vacancy v
    ON v2.VacancyId = v.VacancyId

点击以下链接查看正在运行的演示

SQLFiddle

答案 2 :(得分:0)

您需要LEFT OUTER JOIN来添加没有空缺的用户

SELECT c.[id] 
         , case when va.[candidateid] is null then 'N/A'
           else va.[candidateid]
           END as candidateid
         , case when va.[vacancyid] is null then 'N/A'
           else va.[vacancyid]
           end 
FROM  user  C LEFT OUTER JOIN VacancyApplication VA on c.userid=va.userid  
ORDER BY va.application_date desc

答案 3 :(得分:0)

你可以试试这个。

        select U.UserId,U.Name,U.Email,COALESCE(V.VacancyName, 'N/A') AS LASTAPPLIEDVACANCY from 
    (select USerId, VacancyId, max(Application Date) over(partition by userID)  from VacancyApplication) AS VA 
join Vacancy AS V on
        VA.VacancyId=V.VacancyId join User AS U on VA.UserId=U.UserID