2015-01-13 5 views
0

Я пытаюсь написать запрос, который находит дубликаты. В запросе будут указаны даты последнего заказа 2013 года, а затем соответствующие последним заказам 2014, чтобы найти записи, которые существуют в BOTH годах. Мой код дает мне только данные 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

Поскольку у записи smith есть две даты 2014 года, я ищу последнюю дату на 2014 год.В противном случае MAX date –

ответ

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() функция добавляет число к каждой записи, начиная с 1 в каждой группе, определенной в PARTITION BY (по желанию) и упорядоченным в соответствии с ORDER BY (требуется).

Добавление OVER() в COUNT() позволяет вам получить счет, группируя его без потери деталей, как с GROUP BY.

Таким образом, первый cte добавляет ряд полезных для фильтрации до последней Order_Date в год для каждого Bill_Memmber_ID, то вторая добавляет счетчик сколько лет каждый Bill_Member_ID имеет записей в

Update:. Я не был изначально думая о том, что это ограничивается двумя годами, и считал, что любая многолетняя ситуация является желаемой продукцией. Таким образом, подход Гордона проще с учетом только двухлетнего требования, если вам нужно рассмотреть, где кто-то заказывал в течение какого-то другого года, вы можете использовать этот ответ.

+0

Благодарим вас за комментарий, это здорово помогает мне получить счет за 2013 и 2014 годы, но как новый программист, можете ли вы указать мне, где в коде он находит дубликаты? –

+0

@RamatuVictoriousKuyateh В этой ситуации первый cte нумерует «дубликаты» из 1-n для каждого 'year' /' bill_member_id', если вы «SELECT * FROM cte», вы увидите значения «RN» для дубликатов и мы используем это значение для фильтрации дубликатов 'WHERE RN = 1'. Последующий 'cte' берет одну запись за' год'/'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.

Смежные вопросы