2012-01-23 87 views
0

单位 - HMY,SCODE,hProperty过滤复杂的SQL查询

InsurancePolicy - HMY,hUnit,dtEffective,sStatus

Select MAX(i2.dtEffective) as maxdate, u.hMy, MAX(i2.hmy) as InsuranceId, 
    i2.sStatus 
from unit u 
    left join InsurancePolicy i2 on i2.hUnit = u.hMy 
     and i2.sStatus in ('Active', 'Cancelled', 'Expired') 
where u.hProperty = 2 
Group By u.hmy, i2.sStatus 
order by u.hmy 

这个查询将返回值的保险政策与最新的生效日期( Max(dtEffective))。我添加了Max(i2.hmy),因此如果最近生效日期有多份保险单,它将返回数据库中具有最高编号(i2.hmy)的保单。

假设有一个单位有3个保险单,并附有相同的最新生效日期,并且所有单位都有不同的sStatus'。 结果是这样的:

maxdate UnitID InsuranceID sStatus 
1/23/12 2949  1938   'Active' 
1/23/12 2949  2343   'Cancelled' 
1/23/12 2949  4323   'Expired' 

如何筛选结果,所以,如果有相同单位与同一日期的多个保险政策不同的状态,那么我们选择的保险政策与'Active'首先状态,如果不存在,请选择'Cancelled',如果不存在,请选择'Expired'

+0

我会担心这件事情是否发生。你应该存储datetime ifnormation,所以你可以得到最新的一个,如果他们在同一天。其他明智的方法是最后一次,也许最后的行动被取消了 – HLGEM

回答

0

这似乎是InsurancePolicy的行适当ranking,然后的事情加盟Unit设定的前排名第一行:

; 
WITH ranked AS (
    SELECT 
    *, 
    rnk = ROW_NUMBER() OVER (
     PARTITION BY hUnit 
     ORDER BY dtEffective DESC, sStatus, hmy DESC 
    ) 
    FROM InsurancePolicy 
) 
SELECT 
    i2.dtEffective AS maxdate, 
    u.hMy, 
    i2.hmy AS InsuranceId, 
    i2.sStatus 
FROM Unit u 
    LEFT JOIN ranked i2 ON i2.hUnit = u.hMy AND i2.rnk = 1 
0

你可以做这个工作,一个SQL语句,但这对您日常的t-sql开发人员来说几乎是不可读的。我建议将这个查询分成几个步骤。

首先,我将声明一个表变量,并将不需要操纵的所有记录放入此表(即 - 对于同一日期=没有好记录的单元,不具有多个状态)。

然后,获取需要在其上完成工作的记录列表(同一个UnitID在同一日期的多个状态),并将它们放在表变量中。我会用一个case语句创建该表变量中的 “等级” 栏所示的位置:

伪代码:当激活THEN 1 ELSE WHEN然后又取消了2 ELSE然后当过期3 END

然后删除其中存在2和3的记录1 然后删除记录,其中存在2和3

最后,将此更新的表变量与包含“良好”记录的表变量合并。

在一个SQL语句中很容易被试图做太多事情。分解任务,使其在未来更容易开发并更易于管理。如果你必须在几年内编辑这个SQL,你会感谢你自己,更不用说其他任何可能需要接管你的代码的开发者。