2012-03-02 12 views
6

मैं आदेश की एक तालिका मैं जानता हूँ कि डुप्लिकेटढूँढना डुप्लिकेट आदेश (समय निकटता से)

customer order_number order_date 
    ---------- ------------ ------------------- 
      1    1  2012-03-01 01:58:00 
      1    2  2012-03-01 02:01:00 
      1    3  2012-03-01 02:03:00 
      2    4  2012-03-01 02:15:00 
      3    5  2012-03-01 02:18:00 
      3    6  2012-03-01 04:30:00 
      4    7  2012-03-01 04:35:00 
      5    8  2012-03-01 04:38:00 
      6    9  2012-03-01 04:58:00 
      6   10  2012-03-01 04:59:00 

मैं (eachother के 60 मिनट के भीतर आदेश में एक ही ग्राहक से) सभी डुप्लीकेट ढूंढना चाहते है की है। या तो एक परिणाम जिसमें 'डुप्लिकेट' पंक्तियां या सभी ग्राहकों का एक सेट शामिल है, जो कितने डुप्लिकेट की गणना करते हैं।

यहाँ मैं

SELECT 
    customer, 
    count(*) 
FROM 
    orders 
GROUP BY 
    customer, 
    DATEPART(HOUR, order_date) 
HAVING (count(*) > 1) 

यह वही है की कोशिश की है काम नहीं करता है जब डुप्लिकेट एक दूसरे के 60 मिनट के भीतर हैं, लेकिन 1:58 और 2:02

मैं यानी अलग घंटों में हो रहा है यह भी कोशिश की किया है इस

SELECT 
    o1.customer, 
    o1.order_number, 
    o2.order_number, 
    DATEDIFF(MINUTE,o1.order_date, o2.order_date) AS [diff] 
FROM 
    orders o1 LEFT OUTER JOIN 
    orders o2 ON o1.customer = o2.customer AND o1.order_number <> o2.order_number 
WHERE 
    ABS(DATEDIFF(MINUTE,o1.order_date, o2.order_date)) < 60 

अब यह मेरे सभी प्रतिलिपियों देता है, लेकिन यह भी मुझे डुप्लिकेट आदेश के अनुसार कई पंक्तियों देता है। i.e (o1, o2) और (o2, o1) जो एकाधिक डुप्लीकेट वाले कुछ ऑर्डर नहीं होने पर इतना बुरा नहीं होगा। उन मामलों में मुझे (ओ 1, ओ 2), (ओ 1, ओ 3), (ओ 2, ओ 1), (ओ 2, ओ 3), (ओ 3, ओ 1), (ओ 3, ओ 2) आदि मिलते हैं। मुझे सभी क्रमिकरण मिलते हैं।

किसी के पास कुछ अंतर्दृष्टि है? मैं जरूरी नहीं कि यहां सबसे अच्छा प्रदर्शन करने वाला उत्तर ढूंढ रहा हूं, केवल एक जो काम करता है।

+0

आपके पास एक कैस्केड निर्भरता है। यदि आपके पास आदेश हैं ('0, 59, 118, 177, 236, आदि) * [सभी 59 मिनट एपर्ट] *, आप अपनी खोज का नतीजा क्या चाहते हैं? – MatBailie

+0

@Dems दिलचस्प है। मैं उन सभी डुप्लीकेटों पर विचार करूंगा। हालांकि मैं किसी भी मामले में परिणाम से खुश हूं। –

उत्तर

3
SELECT 
    *, 
    CASE WHEN EXISTS (SELECT * 
         FROM orders AS lookup 
        WHERE customer = orders.customer 
         AND order_date < orders.order_date 
         AND order_date >= DATEADD(hour, -1, order_date) 
        ) 
     THEN 'Principle Order' 
     ELSE 'Duplicate Order' 
    END as Order_Status 
FROM 
    orders 

EXISTS का उपयोग करना और एक सहसंबद्ध उप क्वेरी आप कर सकते हैं ग अगर पिछले घंटे में कोई पूर्व आदेश थे तो बिल्ली।

+0

मानता है कि एक ही समय में कोई भी दो ऑर्डर नहीं होता है। '< AND > =' के बजाय '<= AND > 'में बदला जा सकता है और फिर' id MatBailie

+0

धन्यवाद। मुझे कुछ मामूली चीज़ों को ट्विक करना पड़ा लेकिन अवधारणात्मक रूप से यह मेरे लिए काम करता है। यह एक तरह का समाधान है जो मैं समाधान के बारे में सोच रहा था लेकिन इतने लंबे समय तक इसे देखने के बाद मैंने छोड़ दिया। एक बार फिर धन्यवाद। –

1

हो सकता है कि कुछ इस तरह:

टेस्ट डेटा:

DECLARE @tbl TABLE(customer INT,order_number INT,order_date DATETIME) 

INSERT INTO @tbl 
VALUES 
    (1,1,'2012-03-01 01:58:00'), 
    (1,2,'2012-03-01 02:01:00'), 
    (1,3,'2012-03-01 02:03:00'), 
    (2,4,'2012-03-01 02:15:00'), 
    (3,5,'2012-03-01 02:18:00'), 
    (3,6,'2012-03-01 04:30:00'), 
    (4,7,'2012-03-01 04:35:00'), 
    (5,8,'2012-03-01 04:38:00'), 
    (6,9,'2012-03-01 04:58:00'), 
    (6,10,'2012-03-01 04:59:00') 

क्वेरी

;WITH CTE 
AS 
(
    SELECT 
     MIN(datediff(minute,'1990-1-1',order_date)) OVER(PARTITION BY customer) AS minDate, 
     datediff(minute,'1990-1-1',order_date) AS DateTicks, 
     tbl.customer 
    FROM 
     @tbl AS tbl 
) 
SELECT 
    CTE.customer, 
    SUM(CASE WHEN (CTE.DateTicks-CTE.minDate)<60 THEN 1 ELSE 0 END) 
FROM 
    CTE 
GROUP BY 
    CTE.customer 
+0

यह केवल पहले क्रम की तुलना में है? मिनटों (0,1,2,65,66,67) 'पर होने वाले आदेशों के बारे में क्या? '(1,2,66,67)' के आदेश डुप्लीकेट हैं, लेकिन क्या यह केवल '(1,2) 'नहीं मिलेगा? – MatBailie

+0

+1 मैं इसे अपने वास्तविक डेटा के खिलाफ एक शॉट दे रहा हूं, प्रतिक्रिया के लिए धन्यवाद। –

+0

@ डेम्स: मैं आपका अनुसरण नहीं करता हूं। यह ग्राहक समूह का न्यूनतम हिस्सा लेगा और फिर वर्तमान डेटाटाइम घटाएगा। यह मिनटों (टिक) में पूर्ण डेटाटाइम भी लेगा। – Arion

1

निम्न क्वेरी एक दूसरे के 60 मिनट की निकटता के भीतर आदेश के सभी संभव क्रमपरिवर्तन की पहचान करता है:

DECLARE @orders TABLE (CustomerId INT, OrderId INT, OrderDate DATETIME) 

INSERT INTO @orders 
VALUES 
    (1, 1, '2012-03-01 01:58:00'), 
    (1, 2, '2012-03-01 02:01:00'), 
    (1, 3, '2012-03-01 02:03:00'), 
    (2, 4, '2012-03-01 02:15:00'), 
    (3, 5, '2012-03-01 02:18:00'), 
    (3, 6, '2012-03-01 04:30:00'), 
    (4, 7, '2012-03-01 04:35:00'), 
    (5, 8, '2012-03-01 04:38:00'), 
    (6, 9, '2012-03-01 04:58:00'), 
    (6, 10, '2012-03-01 04:59:00'); 

with ProximityOrderCascade(CustomerId, OrderId, ProximateOrderId, MinutesDifference, OrderDate, ProximateOrderDate) 
as 
(
    select o.customerid, o.orderid, null, null, o.orderdate, o.orderdate 
    from @orders o 
    union all 
    select o.customerid, o.orderid, p.orderid, datediff(minute, p.OrderDate, o.OrderDate), o.OrderDate, p.OrderDate 
    from ProximityOrderCascade p 
    inner join @orders o 
     on p.customerid = o.customerid 
     and abs(datediff(minute, p.OrderDate, o.OrderDate)) between 0 and 60 
     and o.orderid <> p.orderid 
    where proximateorderid is null 
) 
select * from ProximityOrderCascade 
where 
    not ProximateOrderId is null 

वहाँ से, आप अपनी पसंद का एक क्वेरी में परिणाम बदल सकता है। इस फ़ंक्शन के परिणाम केवल 1 और 6 को 'डुप्लिकेट' ऑर्डर के रूप में पहचानते हैं।

CustomerId OrderId  ProximateOrderId MinutesDifference OrderDate    ProximateOrderDate 
----------- ----------- ---------------- ----------------- ----------------------- ----------------------- 
6   9   10    -1    2012-03-01 04:58:00.000 2012-03-01 04:59:00.000 
6   10   9    1     2012-03-01 04:59:00.000 2012-03-01 04:58:00.000 
1   1   3    -5    2012-03-01 01:58:00.000 2012-03-01 02:03:00.000 
1   2   3    -2    2012-03-01 02:01:00.000 2012-03-01 02:03:00.000 
1   1   2    -3    2012-03-01 01:58:00.000 2012-03-01 02:01:00.000 
1   3   2    2     2012-03-01 02:03:00.000 2012-03-01 02:01:00.000 
1   2   1    3     2012-03-01 02:01:00.000 2012-03-01 01:58:00.000 
1   3   1    5     2012-03-01 02:03:00.000 2012-03-01 01:58:00.000 

(8 row(s) affected) 
संबंधित मुद्दे