2012-03-02 14 views
6

ben çiftleriBulma Yinelenen Siparişleri

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 

I (birbirinden 60 dakika içinde aynı müşteri tarafından sipariş) tüm çiftleri bulmak istiyorum biliyorum siparişlerin bir tablo var. Ya "yinelenen" satırlardan oluşan bir sonuç kümesi veya kaç müşterinin toplam sayısını içeren bir müşteri grubu. İşte

çiftleri birbirinden 60 dakika içinde ancak 1.58 ve 2:02 Ben

yani farklı saatlerde geçerlidir diye çalışmıyor

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

Bu

denedim budur Ayrıca bu

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 

denedim Şimdi bu bana yinelenenlerin tümünde verir fakat bu bana yinelenen sipariş başına birden çok satır verir. Birden fazla kopya ile bazı siparişler olmasaydı o kadar da kötü olmazdı (o1, o2) ve (o2, o1). Bu durumlarda (o1, o2), (o1, o3), (o2, o1), (o2, o3), (o3, o1), (o3, o2) vb. Olsun. Tüm permütasyonları elde ederim.

Herkesin biraz anlayışı var mı? Burada en iyi performansa cevap aramak zorunda değilim, sadece işe yarayan.

+0

Kaskad dependancy'niz var. Eğer '(0, 59, 118, 177, 236, vb.)' De olan emirleriniz varsa * [59 dakikalık bir appart] *, aramanızın sonucunun ne olmasını istersiniz? – MatBailie

+0

@Dems ilginç. Tüm bu kopyaları düşünürdüm. Ancak her iki durumda da sonuçtan memnun olurum. –

cevap

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 

ve bağıntılı alt sorgu yapabilirsiniz c son saatte herhangi bir siparişin olup olmadığını kontrol et.

+0

Aynı anda iki emir gerçekleşmez. < AND > = 'yerine <= AND >' olarak değiştirilip 'id MatBailie

+0

Teşekkürler. Birkaç küçük şeyi düzeltmem gerekiyordu ama kavramsal olarak bu benim için çalışıyor. Bu bir çözüm olarak düşündüğüm türden bir şeydi ama uzun süre boyunca baktıktan sonra pes ettim. Tekrar teşekkürler. –

1
böyle

Belki bir şey:

Testi veriler:

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') 

Sorgu

EXISTS kullanma
;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

Bu sadece ilk siparişle karşılaştırılıyor? Dakikalarda gerçekleşen emirlere ne dersiniz? (0,1,2,65,66,67) '? '(1,2,66,67)' de verilen siparişler çoğaltılır, ancak bu sadece '(1,2) 'yi bulmaz mı? – MatBailie

+0

+1 Buna gerçek verilerime karşı bir şans veriyorum, yanıt için teşekkürler. –

+0

@Dems: Seni takip etmiyorum. Bu, müşteri grubunun en azını alır ve daha sonra mevcut datetime değerini çıkarır. Bu da tam tarih bilgisini dakikalar içinde alacaktır (keneler). – Arion

1

aşağıdaki sorgu birbirinden 60 dakikalık yakınlık içinde siparişlerin tüm olası permütasyon tanımlar:

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 

Oradan, sizin seçtiğiniz bir sorguya sonuçları dönüştürebilir. Bu işlevin sonuçları sadece 1 ve 6 numaralı müşterileri 'çift' siparişlere sahip olarak tanımlar.

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)