Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Max innerhalb eines Zeitrahmens mit Datumsduplikaten

Wenn ich das richtig verstanden habe, möchten Sie eindeutige Einträge für einen bestimmten Status in Ihrem Zeitraum zählen ... wenn dies der Fall ist, sollten Sie den DISTINCT verwenden -Klausel in Ihrem count() Änderung von count(*) zu count(distinct Entry_id)

with c (Status_Id, Entry_Id, Start_Date) AS (
  select Status_Id, Entry_Id, Start_Date from tbl where
  (End_Date BETWEEN '19000101' AND '21000101')
  AND ((Start_Date BETWEEN '19000101' AND '21000101')
  OR End_Date <= '21000101'))
select Status_Id, count(distinct Entry_Id) as cnt from 
 (select Entry_Id, max(start_date) as start_date from c
  group by Entry_Id) d inner join
c on c.Entry_Id = d.Entry_Id
and c.start_date = d.start_date
GROUP BY Status_Id WITH ROLLUP

BEARBEITEN

Solange es Ihnen egal ist, welcher Status für einen bestimmten Eintrag zurückgegeben wird, können Sie meiner Meinung nach die innere Abfrage so ändern, dass sie den ersten Status zurückgibt und sich auch dem Status anschließt

with c (Status_Id, Entry_Id, Start_Date) AS (
  select Status_Id, Entry_Id, Start_Date from tbl where
  (End_Date BETWEEN '19000101' AND '21000101')
  AND ((Start_Date BETWEEN '19000101' AND '21000101')
  OR End_Date <= '21000101'))
select c.Status_Id, count(c.Entry_Id) as cnt from 
 (select Entry_Id, Start_Date, (select top 1 Status_id from c where Entry_Id = CC.Entry_Id and Start_Date = CC.Start_Date) as Status_Id
  from (select Entry_Id, max(start_date) as start_date from c
  group by Entry_Id) as CC) d inner join
c on c.Entry_Id = d.Entry_Id
and c.start_date = d.start_date
and c.status_id = d.status_id
GROUP BY c.Status_Id

Ergebnis

Status_id Count
 489       2
 492       1
 495       1