2012-06-12 15 views
5

Ben dellstore2 veritabanı için toplu olarak kullanıcı sayısını hesaplamaya çalışıyorum. Burada cevaplar ve diğer forumlarda baktığımızda, buBirikimli Aylık Toplamlar ve Postgresql

select 
date_trunc('month',orderdate), 
sum(count(distinct(customerid))) 
    over (order by date_trunc('month',orderdate)) 
from orders group by date_trunc('month',orderdate) 

Bu

döndürür kullanılan
2004-01-01 00:00:00.0 979 
2004-02-01 00:00:00.0 1,952 
2004-03-01 00:00:00.0 2,922 
2004-04-01 00:00:00.0 3,898 
2004-05-01 00:00:00.0 4,873 
2004-06-01 00:00:00.0 5,846 
2004-07-01 00:00:00.0 6,827 
2004-08-01 00:00:00.0 7,799 
2004-09-01 00:00:00.0 8,765 
2004-10-01 00:00:00.0 9,745 
2004-11-01 00:00:00.0 10,710 
2004-12-01 00:00:00.0 11,681 

Her ay olduğu

979 
973 
970 
976 
975 
973 
981 
972 
966 
980 
965 
971 
İlk birkaç bakarak ince toplam gibi görünüyor

öğeler. Ben Tüm bu olaylar için

select count(distinct(customerid)) from orders 

çalıştırdığımızda Ama ilk çıkışında 11681 son öğeye kabul etmez

8996 

olsun. Yukarıdaki hesaplamaların aylar boyunca benzersizliği belirleyemediğini tahmin ediyorum. Bu hesaplamanın en hızlı yolu nedir, tercihen kendi kendine birleşmeksizin?

+1

Bazı müşteriler bir kereden fazla şey satın aldılar mı? Farklı aylarda mı? –

+0

@ NikolaMarkovinović @ bu konuda haklısınız, bu yoruma cevap vermelisiniz ... –

+0

@pOcHa Od svih gradova, moj omiljeni Niš .... :-) –

cevap

7

yerine siparişler doğrudan seçmek yerine, bunu böyle bir alt sorgu kullanabilirsiniz:

SELECT OrderDate, 
     SUM(COUNT(DISTINCT customerid)) OVER (ORDER BY OrderDate) 
FROM ( SELECT CustomerID, 
        DATE_TRUNC('MONTH', MIN(OrderDate)) AS OrderDate 
      FROM Orders 
      GROUP BY CustomerID 
     ) AS Orders 
GROUP BY OrderDate 

Ben gerektiği gibi bu işe düşünüyorum. Hala iki yöntemi de Gerekirse

http://sqlfiddle.com/#!1/7a8cc/1

DÜZENLEME

(yani farklı ve çalışan toplam) Bu kullanabilirsiniz:

SELECT OrderDate, 
     COUNT(DISTINCT CustomerID) AS MonthTotal, 
     SUM(COUNT(DISTINCT customerid)) OVER (ORDER BY OrderDate) AS CumulativeTotal, 
     SUM(COUNT(DISTINCT CASE WHEN OrderNumber = 1 THEN customerid END)) OVER (ORDER BY OrderDate) AS CumulativeDistinctTotal 
FROM ( SELECT CustomerID, 
        OrderDate, 
        ROW_NUMBER() OVER(PARTITION BY CustomerID ORDER BY OrderDate) AS OrderNumber 
      FROM Orders 
     ) AS Orders 
GROUP BY OrderDate 

Örnek burada:

http://sqlfiddle.com/#!1/7a8cc/10

+2

+1 - Çok iyi düşünen batman. Gerçekten işe yarayan – MatBailie

+0

ve neden olduğuna dair hiçbir fikrim yok. :) anlamaya çalışacağım. Teşekkürler. – user423805

+1

Birincisi, çoğaltmaları kaldırmak için 'COUNT (DISTINCT CustomerID)' i kullanmak yerine, yinelenen sayılan veri kümesini gruplayarak kaldırılır, böylece sonuçların sayısında DISTINCT olmadan aynı sonuçları alırsınız. İkincisi temel olarak orijinal sorgu ile aynıdır, ek olarak bir "ROW_NUMBER" sütunu eklenir, bu da her müşteri için ilk siparişi tanımlamak için kullanılır, böylece tüm siparişleri ve farklı müşterileri saymak mümkündür. – GarethD