2017-09-03 84 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客戶 –