2017-09-03 83 views
0

我正在修改下面的代码,我没有写并被交给我(相对较新的SQL),它有效地选择地址,但我只想选择具有最新'UDEFVALID_FROM'日期的地址,作为目前如果客户有2个地址,它将选择两个地址。如何选择最近开始日期的记录?

 Select * FROM UDEFCust_Temp_Address ctd 
     WHERE ctd.UDEFVALID_FROM IS NOT NULL 
      AND (GETDATE() >= ctd.UDEFVALID_FROM 
       AND GETDATE() <= ctd.UDEFVALID_TO 
       OR (ctd.UDEFVALID_TO IS NULL or ctd.UDEFVALID_TO>= GETDATE())) 

只是为了进一步向产品中添加以下是完整的SQL:

IF @customer_rule = 'All' 
     BEGIN 
      insert into [etl].[lu_uletters_recipient_addrss_stg] 
      (cnsmr_id,cnsmr_accnt_id,cnsmr_type,addrss_rule,recipientSalutation,recipientName, 
      recipient_addressLine1,recipient_addressLine2,recipient_addressLine3,recipient_addressLine4, 
      recipient_address_pstl_cd,recipient_primaryAddresseType,moreRecipientIndicator,PostalClass,dcmnt_tmplt_shrt_nm) 
      select * 
      from 
      (
      select t.cnsmr_id as cnsmr_id,t.cnsmr_accnt_id as cnsmr_accnt_id, 
      'Primary' as cnsmr_type, 
      'All' as addrss_rule, 
      ctad.UDEFSALUTATION AS recipientSalutation, 
      isnull(ctd.UDEFNAME,ctad.UDEFADDRESSEE) as recipientName, 
      COALESCE(ctd.UDEFADDRESS_addrss_ln_1_txt,ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) as recipient_addressLine1, 
      CASE WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NOT NULL THEN COALESCE(ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) 
        WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NOT NULL THEN ctd.UDEFADDRESS_addrss_ln_3_txt 
        WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NULL THEN NULL 
      END as recipient_addressLine2, 
      ctd.UDEFADDRESS_city_txt as recipient_addressLine3, 
      ctd.UDEFADDRESS_st_txt as recipient_addressLine4, 
      ctd.UDEFADDRESS_pstl_cd as recipient_address_pstl_cd, 
      'P' as recipient_primaryAddresseType, 
      'N' as moreRecipientIndicator, 
      case when ctad.UDEFFOREIGN_ADDR_IND='Y' then 'O' 
        else t.PostalClass end as PostalClass, 
      dcmnt_tmplt_shrt_nm 
      from #tt_cnsmr t 
      --inner join cnsmr_addrss cd on (cd.cnsmr_id = t.cnsmr_id) 
      --inner join cnsmr_accnt_ownrs CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 
      inner join cnsmr_accnt CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 
      left outer join UDEFCust_Temp_Address ctd on (t.cnsmr_id = ctd.cnsmr_id) 
      left outer join UDEFADDITIONAL_CUST_DETAILS ctad on (t.cnsmr_id = ctad.cnsmr_id) 
      where t.dcmnt_tmplt_shrt_nm = @v_tmpl_code/*cao.cnsmr_accnt_ownrshp_typ_cd = 1 
      and cao.cnsmr_accnt_ownrshp_sft_dlt_flg = 'N'*/ 
      and ((ctd.UDEFVALID_FROM IS NOT NULL AND (GETDATE() >= ctd.UDEFVALID_FROM AND GETDATE() <= ctd.UDEFVALID_TO)) 
      OR (ctd.UDEFVALID_TO IS NULL AND (GETDATE() >= isnull(ctd.UDEFVALID_FROM,'1900-01-01 00:00:00')))) 
      union 
      select cao.cnsmr_id as cnsmr_id,cao.cnsmr_accnt_id as cnsmr_accnt_id, 
      'Non-Primary' as cnsmr_type, 
      'All' as addrss_rule, 
      ctad.UDEFSALUTATION AS recipientSalutation, 
      isnull(ctd.UDEFNAME,ctad.UDEFADDRESSEE) as recipientName, 
      COALESCE(ctd.UDEFADDRESS_addrss_ln_1_txt,ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) as recipient_addressLine1, 
      CASE WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NOT NULL THEN COALESCE(ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) 
        WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NOT NULL THEN ctd.UDEFADDRESS_addrss_ln_3_txt 
        WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NULL THEN NULL 
      END as recipient_addressLine2, 
      ctd.UDEFADDRESS_city_txt as recipient_addressLine3, 
      ctd.UDEFADDRESS_st_txt as recipient_addressLine4, 
      ctd.UDEFADDRESS_pstl_cd as recipient_address_pstl_cd, 
      'S' as recipient_primaryAddresseType, 
      'N' as moreRecipientIndicator, 
      case when ctad.UDEFFOREIGN_ADDR_IND='Y' then 'O' 
        else t.PostalClass end as PostalClass, 
      dcmnt_tmplt_shrt_nm 
      from #tt_cnsmr t 
      inner join cnsmr_accnt_ownrs CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 
      --inner join cnsmr_addrss cd on (cd.cnsmr_id = cao.cnsmr_id) 
      left outer join UDEFCust_Temp_Address ctd on (t.cnsmr_id = ctd.cnsmr_id) 
      left outer join UDEFADDITIONAL_CUST_DETAILS ctad on (t.cnsmr_id = ctad.cnsmr_id) 
      where t.dcmnt_tmplt_shrt_nm = @v_tmpl_code 
      and cao.cnsmr_accnt_ownrshp_typ_cd = 2 
      and cao.cnsmr_accnt_ownrshp_sft_dlt_flg = 'N' 
      and ((ctd.UDEFVALID_FROM IS NOT NULL AND (GETDATE() >= ctd.UDEFVALID_FROM AND GETDATE() <= ctd.UDEFVALID_TO)) 
      OR (ctd.UDEFVALID_TO IS NULL AND (GETDATE() >= isnull(ctd.UDEFVALID_FROM,'1900-01-01 00:00:00')))) 
      )stg_data 
      where not exists (select 1 from [etl].[lu_uletters_recipient_addrss_stg] t 
            where t.cnsmr_id = stg_data.cnsmr_id and t.cnsmr_accnt_id = stg_data.cnsmr_accnt_id and t.dcmnt_tmplt_shrt_nm = @v_tmpl_code) 
+0

更换后,您需要'MAX()'日期'组by'在列的其余部分在选择列表中。请做一些功课。你也会学到一些基本的东西。 – niksofteng

+0

感谢您的回应,是的,你是对的我需要掌握SQL的基础知识。我一直在玩最大声明,就像下面这样,但它不起作用,我认为它不符合你的建议,是否需要列出选择中的所有列,而不是仅仅使用*:选择* FROM UDEFCust_Temp_Address ctd WHERE (select max(ctd.UDEFVALID_FROM)) –

回答

2

在SQLServer2008的+

尝试

; With cte as (

    Select *, row_number() over (partition by CustomerId order by UDEFVALID_FROM desc) rn 
FROM UDEFCust_Temp_Address ctd 
WHERE ctd.UDEFVALID_FROM IS NOT NULL 
     AND (GETDATE() >= ctd.UDEFVALID_FROM 
      AND GETDATE() <= ctd.UDEFVALID_TO 
      OR (ctd.UDEFVALID_TO IS NULL or ctd.UDEFVALID_TO>= GETDATE())) 
) 
Select * from cte where rn=1 

或者使用子查询像

select * from (
    Select *, row_number() over (partition by CustomerId order by UDEFVALID_FROM desc) rn 
    FROM UDEFCust_Temp_Address 
) 
where rn=1 

查询子查询

declare @v_tmpl_code nvarchar(10); 

insert into [etl].[lu_uletters_recipient_addrss_stg] (cnsmr_id,cnsmr_accnt_id,cnsmr_type,addrss_rule,recipientSalutation,recipientName 
, recipient_addressLine1,recipient_addressLine2,recipient_addressLine3,recipient_addressLine4 
, recipient_address_pstl_cd,recipient_primaryAddresseType,moreRecipientIndicator,PostalClass,dcmnt_tmplt_shrt_nm) 
select * from (select t.cnsmr_id as cnsmr_id,t.cnsmr_accnt_id as cnsmr_accnt_id, 'Primary' as cnsmr_type, 'All' 
as addrss_rule, ctad.UDEFSALUTATION AS recipientSalutation, isnull(ctd.UDEFNAME,ctad.UDEFADDRESSEE) as recipientName 
, COALESCE(ctd.UDEFADDRESS_addrss_ln_1_txt,ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) as recipient_addressLine1 
, CASE WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NOT NULL THEN COALESCE(ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) 
WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NOT NULL 
THEN ctd.UDEFADDRESS_addrss_ln_3_txt WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NULL 
THEN NULL END as recipient_addressLine2, ctd.UDEFADDRESS_city_txt as recipient_addressLine3, ctd.UDEFADDRESS_st_txt 
as recipient_addressLine4, ctd.UDEFADDRESS_pstl_cd as recipient_address_pstl_cd, 'P' as recipient_primaryAddresseType 
, 'N' as moreRecipientIndicator, case when ctad.UDEFFOREIGN_ADDR_IND='Y' then 'O' else t.PostalClass 
end as PostalClass, dcmnt_tmplt_shrt_nm 
from #tt_cnsmr t 

inner join cnsmr_addrss cd on (cd.cnsmr_id = t.cnsmr_id) 
inner join cnsmr_accnt_ownrs CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 
inner join cnsmr_accnt CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 

-- this is the replaced query 
left outer join (Select *, row_number() over (partition by CustomerId order by UDEFVALID_FROM desc) rn FROM UDEFCust_Temp_Address) ctd on t.cnsmr_id = ctd.cnsmr_id and ctd.rn=1 

left outer join UDEFADDITIONAL_CUST_DETAILS ctad on (t.cnsmr_id = ctad.cnsmr_id) 
where t.dcmnt_tmplt_shrt_nm = @v_tmpl_code and cao.cnsmr_accnt_ownrshp_typ_cd = 1 
and cao.cnsmr_accnt_ownrshp_sft_dlt_flg = 'N' 
    and ((ctd.UDEFVALID_FROM IS NOT NULL AND (GETDATE() >= ctd.UDEFVALID_FROM 
AND GETDATE() <= ctd.UDEFVALID_TO)) OR (ctd.UDEFVALID_TO IS NULL AND (GETDATE() >= isnull(ctd.UDEFVALID_FROM,'1900-01-01 00:00:00')))) 

union 

select cao.cnsmr_id as cnsmr_id,cao.cnsmr_accnt_id as cnsmr_accnt_id, 'Non-Primary' as cnsmr_type, 'All' as addrss_rule, 
ctad.UDEFSALUTATION AS recipientSalutation, isnull(ctd.UDEFNAME,ctad.UDEFADDRESSEE) as recipientName 
, COALESCE(ctd.UDEFADDRESS_addrss_ln_1_txt,ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) 
as recipient_addressLine1, CASE WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NOT NULL 
THEN COALESCE(ctd.UDEFADDRESS_addrss_ln_2_txt,ctd.UDEFADDRESS_addrss_ln_3_txt) 
WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NOT NULL 
THEN ctd.UDEFADDRESS_addrss_ln_3_txt WHEN ctd.UDEFADDRESS_addrss_ln_1_txt IS NULL AND ctd.UDEFADDRESS_addrss_ln_2_txt IS NULL 
THEN NULL END as recipient_addressLine2, ctd.UDEFADDRESS_city_txt as recipient_addressLine3, ctd.UDEFADDRESS_st_txt 
as recipient_addressLine4, ctd.UDEFADDRESS_pstl_cd as recipient_address_pstl_cd, 'S' as recipient_primaryAddresseType, 'N' 
as moreRecipientIndicator, case when ctad.UDEFFOREIGN_ADDR_IND='Y' then 'O' else t.PostalClass end as PostalClass, dcmnt_tmplt_shrt_nm 
from #tt_cnsmr t inner join cnsmr_accnt_ownrs CAO on (t.cnsmr_id = cao.cnsmr_id and t.cnsmr_accnt_id = cao.cnsmr_accnt_id) 
inner join cnsmr_addrss cd on (cd.cnsmr_id = cao.cnsmr_id) left outer join UDEFCust_Temp_Address ctd on (t.cnsmr_id = ctd.cnsmr_id) 
left outer join UDEFADDITIONAL_CUST_DETAILS ctad on (t.cnsmr_id = ctad.cnsmr_id) where t.dcmnt_tmplt_shrt_nm = @v_tmpl_code 
    and cao.cnsmr_accnt_ownrshp_typ_cd = 2 and cao.cnsmr_accnt_ownrshp_sft_dlt_flg = 'N' and ((ctd.UDEFVALID_FROM IS NOT NULL 

    AND (GETDATE() >= ctd.UDEFVALID_FROM AND GETDATE() <= ctd.UDEFVALID_TO)) OR (ctd.UDEFVALID_TO IS NULL 
    AND (GETDATE() >= isnull(ctd.UDEFVALID_FROM,'1900-01-01 00:00:00')))))stg_data where 
    not exists (select 1 from [etl].[lu_uletters_recipient_addrss_stg] t 
    where t.cnsmr_id = stg_data.cnsmr_id and t.cnsmr_accnt_id = stg_data.cnsmr_accnt_id and t.dcmnt_tmplt_shrt_nm = @v_tmpl_code) 
+0

感谢您花时间回复开斋节。我收到和错误消息说不正确的语法附近的关键字'过'我需要做一些特定于我的表的更改吗? –

+0

对不起,我已经纠正它 –

+0

这是在row_号码,它必须是row_number() –

-1

您可以通过组&为了条款做到这一点,如下(与上垒正确的列名替换CUSTID什么要通过解决组):

Select * FROM UDEFCust_Temp_Address ctd WHERE 
           ctd.UDEFVALID_FROM IS NOT NULL AND (GETDATE() >= ctd.UDEFVALID_FROM AND GETDATE() <= ctd.UDEFVALID_TO 
     OR (ctd.UDEFVALID_TO IS NULL or ctd.UDEFVALID_TO>= GETDATE())) 
     group by custId order by UDEFVALID_TO desc 
+0

感谢您花时间回复Chandan。所以我换了custId与cnsmr_id(相关列),但我收到和表中的另一列的错误,说明它是无效的,因为它不包含在聚合函数或GROUP BY子句中,你有什么想法吗? –

+0

是的,这个错误依赖于SQL版本。而不是选择*,把列名称我选择,并按顺序也相同。 –

+0

啊,太棒了谢谢Chandan!现在这个工作,所以如果一个客户(cnsmr_id)有2个地址,我只想根据MAX valid_from日期选择1个地址,我会怎么做呢?道歉,如果我错过了显而易见的选择语句目前返回2客户地址为1客户 –