使用最大日期时,SQL值会消失

时间:2018-01-18 12:22:42

标签: sql sql-server-2005

第一次在这里发帖并有一个我希望有人可以提供帮助的查询,我试图寻找答案,但没有任何快乐。

当我使用下面的SQL查找值(在本例中为eb.annualvalue)时,它会返回多个值,因为没有结束日期输入到eb表中,并且有太多员工没有结束日期让我关闭

LEFT JOIN
(
    SELECT
        eb.empid, eb.bencode, eb.currencycode AS [currencycode], eb.notes AS [notes], eb.annualvalue
    FROM
        employeebenefit AS [eb]
    WHERE
             eb.bencode IN ('US 401K Plan')
        AND (eb.enddate IS NULL OR eb.enddate >= '20180101')
)
    AS eb26
        ON eb26.empid = e.empid

但是,当我使用MAX startdate(下面的代码)时,它会返回正确的数字或​​行,但是,eb.annualvalue数字会消失。

LEFT JOIN
(
    SELECT
        eb.empid, eb.bencode, eb.currencycode AS [currencycode], eb.notes AS [notes], eb.annualvalue
    FROM
        employeebenefit AS [eb]
    WHERE
             eb.bencode IN ('US 401K Plan')
        AND (eb.enddate IS NULL OR eb.enddate >= '20180101')
        AND (eb.startdate = (SELECT MAX(eb.startdate) FROM employeebenefit AS [eb]))
)
    AS eb26
        ON eb26.empid = e.empid

非常感谢任何帮助。谢谢Dan。

2 个答案:

答案 0 :(得分:0)

如果我不明白你的问题,你可以使用下面的代码

OUTER APPLY 
(
    SELECT TOP 1
        eb.empid, eb.bencode, eb.currencycode AS [currencycode], eb.notes AS [notes], eb.annualvalue
    FROM
        employeebenefit AS [eb]
    WHERE
            eb.empid = e.empid 
        AND eb.bencode IN ('US 401K Plan')
        AND (eb.enddate IS NULL OR eb.enddate >= '20180101')
    ORDER BY
        eb.startdate DESC
)
    AS eb26

答案 1 :(得分:0)

这听起来像一个greatest-n-per-group问题,你只需要每个员工一行,每个员工有很多行。我不是100%清楚你想如何选择那一行,但我可以举一个例子。

理想情况下,您可以使用ROW_NUMBER(),但这只会从SQL Server 2008开始生效。

两个公共替代方案是:
  - 两次加入您的数据。一旦找到每个用户的“最高日期”,再次找到整行   - 使用相关的子查询来计算个人的最佳行(仍然真正加入两次)

简单-自连接:

LEFT JOIN
(
    SELECT
        empid,
        MAX(startdate)    AS max_startdate
    FROM
        employeebenefit
    WHERE
             bencode IN ('US 401K Plan')
        AND (enddate IS NULL OR enddate >= '20180101')
    GROUP BY
        empid
)
    latest_employeebenefit
        ON latest_employeebenefit.empid = e.empid
LEFT JOIN
    employeebenefit
        ON   employeebenefit.empid     = latest_employeebenefit.empid
        AND  employeebenefit.startdate = latest_employeebenefit.max_startdate
        AND  employeebenefit.bencode IN ('US 401K Plan')
        AND (employeebenefit.enddate IS NULL OR employeebenefit.enddate >= '20180101')

这具有“功能”,如果两个这样的记录都匹配max_startdate (一个平局),那么两者都将通过。通常这是不可能的,通常是可取的,这取决于您的数据和您的需求。

加入的相关子查询:

LEFT JOIN
    employeebenefit
         ON  employeebenefit.id =
             (
                 SELECT TOP(1) lookup.id
                   FROM employeebenefit  AS lookup
                  WHERE lookup.empid = e.empid           -- the correlated bit
                    AND lookup.bencode IN ('US 401K Plan')
                    AND (lookup.enddate IS NULL OR lookup.enddate >= '20180101')
               ORDER BY lookup.startdate DESC
             )

这略有不同,因为它总是只返回一行。如果仅按startdate排序时可能会出现平局,通常最好将另一列添加到ORDER BY,即使它只是id列,也可以确保结果具有确定性。< / p>