2015-01-13 23 views
0

我試圖編寫查找重複的查詢。該查詢將查看最新的2013年訂單日期,然後匹配最新的2014年訂單,以查找在這兩年中存在的記錄。我的代碼只給了我2013年的數據,而不是2013年和2014年。所以我想顯示這兩年的重複。SQl服務器表中的重複記錄不同年

例如下面是樣本數據

Bill_Member_ID........Lname....................Order_Date 
123..........................Smith...............01/05/2013 
123..........................Smith...............02/15/2014 
123..........................Smith...............02/18/2014 
456..........................Jones...............01/07/2013 
789..........................Brown...............01/05/2013 
789..........................Brown...............02/17/2014 
789..........................Brown...............03/17/2014 
992..........................White...............03/15/2013 
992..........................White...............01/05/2014 

於是我應該得到的

Bill_Member_ID........Lname....................Order_Date  
123..........................Smith...............01/05/2013 
123..........................Smith...............02/18/2014 
789..........................Brown...............01/05/2013 
789..........................Brown...............03/17/2014 
992..........................White...............03/15/2013 
992..........................White...............01/05/2014 

這裏一回是我的代碼

SELECT 
    OMFMC.BILL_MASTER_CUSTOMER_ID, 
    OMFMC.BILL_FIRST_NAME, 
    OMFMC.BILL_LAST_NAME, 
    OMFMC.BILL_LABEL_NAME, 
    OMFMC.BILL_PRIMARY_EMAIL_ADDRESS, 
    OMFMC.BILL_ADDRESS_1, 
    OMFMC.BILL_ADDRESS_2, 
    OMFMC.BILL_CITY, 
    OMFMC.BILL_STATE, 
    OMFMC.BILL_POSTAL_CODE, 
    CMI.NATIONAL_LEVEL2, 
    MAX(OMFMC.ORDER_DATE), 
    OMFMC.ORDER_DATE, 
    FT.PAYMENT_AMOUNT, 
SUM(FT.PAYMENT_AMOUNT)as SUM 


FROM 
    CUSTOMER CUSTOMER_IN_TRIBUTE_TO 

RIGHT OUTER JOIN ORDER_FND_DETAIL OFD 
    ON (CUSTOMER_IN_TRIBUTE_TO.MASTER_CUSTOMER_ID=OFD.IN_TRIBUTE_TO_MAST_CUST 
    and CUSTOMER_IN_TRIBUTE_TO.SUB_CUSTOMER_ID=OFD.IN_TRIBUTE_TO_SUB_CUST) 


RIGHT OUTER JOIN ORDER_MBR_FND_MTG_CUS_INFO_VW OMFMC 
    ON (OMFMC.ORDER_NO=OFD.ORDER_NO 
    and OMFMC.ORDER_LINE_NO = OFD.ORDER_LINE_NO ) 


LEFT OUTER JOIN CUS_CURRENT_MEMBERSHIP_INFO CMI 
    ON (CMI.MASTER_CUSTOMER_ID=OMFMC.BILL_MASTER_CUSTOMER_ID 
    and CMI.SUB_CUSTOMER_ID=OMFMC.BILL_SUB_CUSTOMER_ID) 


LEFT OUTER JOIN FAR_TXN FT 
    ON (FT.ORDER_NO=OMFMC.ORDER_NO 
    and FT.ORDER_LINE_NO=OMFMC.ORDER_LINE_NO) 


WHERE 

OMFMC.ORDER_STATUS_CODE='A' 
AND OMFMC.LINE_STATUS_CODE = 'A'   
AND OMFMC.ORDER_STATUS_CODE = 'A' 
AND OMFMC.LINE_STATUS_CODE = 'A' 
AND OMFMC.BILL_CUSTOMER_CLASS_CODE Not IN ('TEST_MBR','STAFF') 
AND FUND in ('FOSFN' , 'MFUND') 
and(DATEPART(year, OMFMC.ORDER_DATE) ='2013') 
and OMFMC.BILL_MASTER_CUSTOMER_ID In (

(select OMFMC.BILL_MASTER_CUSTOMER_ID 
From ORDER_MBR_FND_MTG_CUS_INFO_VW OMFMC 
where (DATEPART(year, OMFMC.ORDER_DATE) ='2014')) 
) 

GROUP BY 
    OMFMC.BILL_LABEL_NAME, 
    OMFMC.BILL_FIRST_NAME, 
    OMFMC.BILL_LAST_NAME, 
    OMFMC.ORDER_DATE, 
    OMFMC.CAMPAIGN, 
    OMFMC.FUND, 
    OMFMC.PRODUCT_CODE, 
    OMFMC.BILL_MASTER_CUSTOMER_ID, 
    OMFMC.BILL_COMPANY_NAME, 
    OMFMC.BILL_COUNTRY_DESCR, 
    OMFMC.BILL_LAST_FIRST_NAME, 
    OMFMC.ORDER_NO, 
    OMFMC.COMMENTS, 
    year(OMFMC.ORDER_DATE), 
    month(OMFMC.ORDER_DATE), 
    OMFMC.BILL_COUNTRY_CODE, 
    CMI.NATIONAL_LEVEL2, 
    CMI.NATIONAL_SINCE_DATE, 
    CMI.CYCLE_END_DATE, 
    OMFMC.BILL_FORMATTED_DETAIL + OMFMC.BILL_FORMATTED_ADDRESS, 
    OMFMC.BILL_PRIMARY_EMAIL_ADDRESS, 
    OMFMC.BILL_ADDRESS_1, 
    OMFMC.BILL_CITY, 
    OMFMC.BILL_STATE, 
    OMFMC.BILL_POSTAL_CODE, 
    OMFMC.BILL_ADDRESS_2, 
    OMFMC.BILL_ADDRESS_3, 
    OMFMC.BILL_ADDRESS_4, 
    OFD.IN_TRIBUTE_TO_DESCR, 
    CUSTOMER_IN_TRIBUTE_TO.LABEL_NAME, 
    OFD.TRIBUTE_TYPE_CODE, 
    OMFMC.MARKET_CODE, 
    OMFMC.BILL_JOB_TITLE, 
    FT.PAYMENT_AMOUNT 



HAVING SUM(FT.PAYMENT_AMOUNT) < 0 

Order By BILL_MASTER_CUSTOMER_ID 
+0

你說比你應該得到重複的記錄,那麼爲什麼在你想要的輸出只有2行史密斯?你不應該回到'Smith ............... 02/15/2014'嗎? –

+0

由於史密斯記錄有兩個2014年的日期,我期待獲取2014年的最新日期。否則MAX日期 –

回答

0

忽視查詢並專注於您的樣本集簡化了一點,您可以使用ROW_NUMBER()的幾個步驟獲得您想要的輸出,以及一個COUNT()OVER()

;with cte AS (SELECT *,ROW_NUMBER() OVER(PARTITION BY Bill_Member_ID,YEAR(Order_Date) ORDER BY Order_Date DESC) AS RN 
       FROM YourTable 
       WHERE YEAR(Order_Date) IN (2013,2014) 
      ) 
    ,cte2 AS (SELECT *,COUNT() OVER(PARTITION BY Bill_Member_ID) AS Yr_CT 
       FROM cte 
       WHERE RN = 1 
      ) 
SELECT Bill_Member_ID,Lname,Order_Date 
FROM cte2 
WHERE Yr_CT > 1 
ORDER BY Bill_Member_ID,Order_Date 

ROW_NUMBER()功能增加了一些給每個記錄,根據ORDER BY從1開始每在PARTITION BY(可選)定義和有序組(必需)。

OVER()添加到COUNT()可讓您通過分組獲得計數,而不會像在GROUP BY中那樣丟失詳細信息。

所以第一cte增加了大量用於過濾的最新Order_Date每年爲每個Bill_Memmber_ID有用,第二增加了多少年每個Bill_Member_ID有記錄的計數

更新:我起初並不考慮將其限制爲2年,並將任何多年的情況視爲預期產出。因此,考慮到只有2年的要求,Gordon的方法更簡單了,如果您需要考慮某人在其他幾年內的訂單可以使用此答案。

+0

感謝您的評論,這對於幫助我獲得2013年和2014年的數據非常有幫助,但是作爲一名新程序員,您能指出我在代碼中哪裏找到重複內容? –

+0

@RamatuVictoriousKuyateh在這種情況下,第一個cte從每個'year' /'bill_member_id'的1-n開始編號爲「duplicates」,如果您選擇* FROM cte,您將看到重複的RN值,我們使用該值過濾掉WHERE RN = 1'的重複項。隨後的'cte'每個'year' /'bill_member_id'獲得一條記錄,並獲得'bill_member_id'記錄多少年的計數。 –

2

如果您在SQL Server這樣做,那麼你可以使用窗口功能:

select s.* 
from (select s.*, 
      min(year(order_date) over (partition by Bill_Member_ID) as minyear, 
      max(year(order_date) over (partition by Bill_Member_ID) as maxyear, 
      row_number() over (partition by Bill_Member_ID, year(order_date) order by order_date desc) as seqnum 
     from sample s 
     where year(order_date) in (2013, 2014) 
    ) s 
where minyear <> maxyear and seqnum = 1; 

提交查詢每個成員的最小和最大的一年,以及分配在一個序列號,記錄每年。

外部where驗證有兩年(如果您願意,可以更明確地寫入where minyear = 2013 and maxyear = 2014)並從每年中選擇一條記錄。

我不確定sample如何與您擁有的表格相關聯。您可以隨時使用子查詢或CTE來定義它。

+0

我最初並沒有想到它被限制在2年之內,這是一種更乾淨的方法。 –

+0

非常感謝您的回覆,雖然它清楚瞭解您如何獲取最大和最小日期,您能指出我在代碼中找到重複項的位置嗎?非常感謝你,因爲我還是一名新程序員。 :) –

+0

@RamatuVictoriousKuyateh。 。 。重複項來自'minyear <> maxyear' - 兩年內必須有記錄才能找到任何記錄。 –

0
select s1.id, s1.name, s1.orderDate as [date 2013], s2.orderDate as [date 2014] 
from 
( select id, name, max(orderDate) as [orderDate] 
    from cusOrder 
    where DatePart(yy, orderDate) = '2013' 
    group by id, name) as s1 
join 
( select id, name, max(orderDate) as [orderDate] 
    from cusOrder 
    where DatePart(yy, orderDate) = '2014' 
    group by id, name) as s2 
on s1.id = s2.id 
0

您也可以嘗試臨時表或CTE比較。