逻辑只在结果集中获得一行

时间:2016-03-31 16:31:48

标签: sql tsql sql-server-2012

我坚持要建立逻辑。任何人都可以帮助我吗?

要求:

对于privacyType ='主要地址'如果有> 1行,其中SI0_ADDR.ADDR_TYPE_CODE =' M',则显示currentDate()在SI0_ADDR.ADDR_EFF_DATE和SI0_ADDR.ADDR_EXPR_DATE之间的行。

我的查询是:

select STU_ID
      ,case when Privacyflag = '' then 'N'
            else Privacyflag
        end Privacyflag
      ,type from (
select a.STU_ID,Privacyflag,a.type 
  ,ROW_NUMBER() OVER ( ORDER BY ADDR_EXPR_DATE DESC) disp_nm  from (
select ad.STU_ID, case when ad.ADDR_TYPE_CODE = 'M' then ad.ADDR_PRIVACY_FLAG
                       when ad.ADDR_TYPE_CODE=''  then 'N'
                  end Privacyflag, 'Primary Phone' type
                , case when ADDR_EXPR_DATE = '1900-01-01' then '2100-12-31'
                       else ADDR_EXPR_DATE
                 end as ADDR_EXPR_DATE

from SI0_ADDR ad
where ad.STU_ID = @studentid ) a
where Privacyflag is not null
) ab
where ab.disp_nm = '1'

这种逻辑在某些情况下不起作用

1 个答案:

答案 0 :(得分:0)

您没有以任何方式按日期排位,这是您要求的一部分。您的查询不需要这么多嵌套子查询。 PrivacyFlag似乎不是您问题的一部分,因此我没有将其用于此示例。您的示例显示Primary Phone,但您的问题涉及Primary Address,因此我不确定如何解决这个问题。

在任何情况下,这是一个非常简单的示例,显示数据,以及如何提取具有最新到期日期的一个记录,以及最新生效日期(如果有两个)具有相同失效日期的记录。)

create table #temp (stu_id int, type varchar(10), address varchar(50), eff_date datetime, expr_date datetime)

insert into #temp values
(1, 'primary', '123 NW 52nd', '1/1/2016', '1/1/1900'),
(1, 'primary', '942 SE 33rd', '1/2/2016', '12/31/2016'),
(1, 'primary', '721 SW 22nd', '4/1/2015', '1/1/1900')

select top 1 *
from   (
         select stu_id
               ,type
               ,address
               ,eff_date
               ,case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end as expr_date
         from   #temp
         where  stu_id = 1
           and  type = 'primary'
       ) as a
where  getdate() between eff_date and expr_date
order by a.expr_date desc, a.eff_date desc

drop table #temp

您甚至可以使用零子查询来执行此操作,但是您需要将case语句复制到查询的whereorder by部分:< / p>

select top 1
       stu_id
      ,type
      ,address
      ,eff_date
      ,case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end as expr_date
from   #temp
where  stu_id = 1
  and  type = 'primary'
  and  getdate() between eff_date and case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end
order by case when expr_date = '1/1/1900' then '12/31/2100' else expr_date end desc
      ,eff_date desc

使用如此小的数据集,showplan没有表明哪个查询最有效;它为两个查询显示了相同的查询计划,除了第一个select语句需要7个CPU周期来编译计划,第二个select语句需要2个CPU周期来编译计划。您可能希望针对具有索引等的实际表上的较大数据集进行测试,并查看哪些表现最佳。