简体   繁体   English

如何选择最近开始日期的记录?

[英]How do I select records with the most recent start date?

I'm looking to amend the below code that I didn't write and was handed over to me (relatively new to SQL), effectively it selects addresses however I only want to select addresses with the latest 'UDEFVALID_FROM' date, as currently if there are 2 addresses for a customer it will select both. 我想修改以下我未写并移交给我的代码(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() ))

Just to further add onto this here is the full SQL: 为了进一步补充说明,这里是完整的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)

In sqlServer2008 + 在sqlServer2008 +

Try 尝试

 ; 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

Or use subQuery like 或使用像子查询

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

your query after replace by subquery 被子查询替换后的查询

 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)

You can achieve this by group & order clause, as below (replace custId with the correct column name for base on what you want address in group by) : 您可以通过group&order子句实现此目的,如下所示(根据要在group by中寻址的内容,将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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM