过滤复杂的SQL查询

时间:2012-01-23 22:44:52

标签: sql-server sql-server-2005 tsql

单位 - hmy,scode,hProperty

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),因此如果最新生效日期有多个保单政策,它将返回数据库中ID最高(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'

2 个答案:

答案 0 :(得分:0)

这似乎是InsurancePolicyUnit行的正确问题,然后将; 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 加入到前者排名靠前的行集中:

{{1}}

答案 1 :(得分:0)

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

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

然后,获取需要完成工作的记录列表(同一UnitID在同一日期的多个状态)并将它们放在表变量中。我将使用case语句在此表变量中创建一个“rank”列,如下所示:

  

伪代码:当有效时,那么当它已经过期时,那么当它已经过期那么3结束

然后删除2和3存在的记录1 然后删除2存在且3

的记录

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

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