Ich bin nicht sicher, wie diese Lösung skaliert - aber mit einigen guten Indexkandidaten und menschenwürdige Daten Housekeeping, wird es funktionieren ..
Sie werden einige zusätzliche Informationen für den Anfang brauchen, und normalisieren Sie Ihre Daten. Sie müssen das Startdatum der ersten Ladeperiode für jeden Kunden kennen. Speichern Sie das also in einer Kundentabelle.
Hier sind die Tabellen I verwendet:
create table #channelViews
(
custId int, channelId int, viewDate datetime
)
create table #channel
(
channelId int, channelName varchar(max)
)
create table #customer
(
custId int, custname varchar(max), chargingStartDate datetime
)
ich einige Daten füllen werde. Ich erhalte nicht die gleichen Ergebnisse wie Ihre Beispielausgabe, da ich für jeden Kunden nicht die entsprechenden Starttermine habe. Kunde 2 wird jedoch OK sein.
insert into #channel (channelId, channelName)
select 1, 'ABSS'
union select 2, 'STHHG'
union select 4, 'XGGTS'
union select 3, 'SSJ'
union select 7, 'UUJKS'
union select 8, 'AKKDC'
union select 9, 'GGSK'
insert into #customer (custId, custname, chargingStartDate)
select 1, 'A', '4 Jan 2016'
union select 2, 'B', '19 Jan 2016'
union select 3, 'C', '5 Jan 2016'
union select 6, 'D', '5 Jan 2016'
insert into #channelViews (custId, channelId, viewDate)
select 1,1,'2016-01-09'
union select 2,2,'2016-01-19'
union select 3,4,'2016-01-09'
union select 6,4,'2016-01-09'
union select 2,2,'2016-01-26'
union select 2,2,'2016-01-28'
union select 1,3,'2016-01-28'
union select 1,1,'2016-01-28'
union select 2,2,'2016-02-02'
union select 2,7,'2016-02-10'
union select 2,8,'2016-02-10'
union select 2,9,'2016-02-10'
union select 2,9,'2016-02-11'
union select 2,7,'2016-02-27'
Und hier ist die etwas unleidy Abfrage, in einer einzigen Aussage. Die beiden zugrunde liegenden Unterabfragen sind tatsächlich die gleichen Daten, daher könnte es geeignetere/effizientere Möglichkeiten geben, diese zu generieren.
Wir müssen jeden Kanal, der in derselben Ladeperiode C für den vorherigen Monat berechnet wurde, von der Abrechnung ausschließen. Dies ist die Essenz des Beitritts. Ich habe einen Right-Join verwendet, so dass ich alle derartigen Übereinstimmungen von den Ergebnissen ausschließen konnte (unter Verwendung von old.custId is null
).
select c.custId, c.[custname], [month], count(*) [count] from
(
select new.custId, new.channelId, new.month, new.chargingPeriod
from
(
select distinct cv.custId, cv.channelId, month(viewdate) [month], (convert(int, cv.viewDate) - convert(int, c.chargingStartDate))/15 chargingPeriod
from #channelViews cv join #customer c on cv.custId = c.custId
) old
right join
(
select distinct cv.custId, cv.channelId, month(viewdate) [month], (convert(int, cv.viewDate) - convert(int, c.chargingStartDate))/15 chargingPeriod
from #channelViews cv join #customer c on cv.custId = c.custId
) new
on old.custId = new.custId
and old.channelId = new.channelId
and old.month = new.Month -1
and old.chargingPeriod = new.chargingPeriod
where old.custId is null
group by new.custId, new.month, new.chargingPeriod, new.channelId
) filteredResults
join #customer c on c.custId = filteredResults.custId
group by c.custId, [month], c.custname
order by c.custId, [month], c.custname
Und schließlich meine Ergebnisse:
custId custname month count
1 A 1 3
2 B 1 1
2 B 2 4
3 C 1 1
6 D 1 1
Diese Abfrage macht das Gleiche:
select c.custId, c.custname, [month], count(*) from
(
select cv.custId, min(month(viewdate)) [month], cv.channelId
from #channelViews cv join #customer c on cv.custId = c.custId
group by cv.custId, cv.channelId, (convert(int, cv.viewDate) - convert(int, c.chargingStartDate))/15
) x
join #customer c
on c.custId = x.custId
group by c.custId, c.custname, x.[month]
order by custId, [month]
Keine Daten für 2015 in der Tabelle? – jarlh
Wie lauten die Regeln für den Abrechnungszyklus? sind sie auf festen Daten oder ändern sie sich? –
Es kann getan werden, aber die Abrechnungszyklen müssen irgendwo definiert werden (entweder in Code oder in einer Tabelle). Gibt es für jeden Kunden eindeutige Zeiträume oder sind die Abrechnungszyklen für alle gleich? – Sturgus