Sql server 过滤复杂的SQL查询

Sql server 过滤复杂的SQL查询,sql-server,sql-server-2005,tsql,Sql Server,Sql Server 2005,Tsql,单位-hmy、scode、hProperty 保险单-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'

单位-hmy、scode、hProperty

保险单-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份保单,且保单的最新生效日期相同,且所有保单的状态都不同。 结果如下所示:

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

我如何过滤结果,以便如果同一单位和同一日期有多份状态不同的保单,那么我们首先选择状态为
“活动”
的保单,如果不存在,则选择
“取消”
,如果不存在,选择
'Expired'

这似乎是一个适当的
保险单
行的问题,然后将
单元
加入到前者的顶级行集合中:

;
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

您可以使用一条SQL语句来实现这一点,但对于您的日常t-SQL开发人员来说,这几乎是不可读的。我建议把这个问题分成几个步骤

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

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

伪代码:激活时,取消时为1,过期时为2,结束时为3

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

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


在一条SQL语句中,很容易陷入太多的尝试之中。将任务分解,使其更易于开发,将来更易于管理。如果您必须在几年后编辑此SQL,您将感谢您自己,更不用说任何其他可能不得不接管您的代码的开发人员。

如果发生这种情况,我会很担心。您应该存储datetime ifnormation,以便在它们位于同一日期时可以获取最新的。另一个明智的做法是如何确定活动是最后一次,也许最后一次活动被取消了