2017-04-06 4 views
0

Ich bin schwer zu finden, eine bessere Lösung für die Auswahl von einzigartigen Datensätzen aus meinem Benutzer Anruf Datentabelle. Meine Tabellenstruktur ist wie folgt:SQL: Filter Datensätze basierend auf Datensatz Erstellungsdatum und anderen Kriterien

SELECT [MarketName], 
     [WebsiteName] , 
     [ID] , 
     [UserID], 
     [CreationDate], 
     [CallDuration], 
     [FromPhone] , 
     [ToPhone], 
     [IsAnswered], 
     [Source] 
FROM [dbo].[UserCallData] 

Es gibt mehrere Einträge in dieser Tabelle mit unterschiedlichen und gleichen IDs. Ich wollte überprüfen, ob [FromPhone] und [ToPhone] in den letzten 3 Monaten mehrfach vorhanden ist. Wenn ja, wollte ich den ersten Datensatz mit allen Spalten auf Basis von [CreationDate] auswählen, die Anzahl der Vorkommen als TotalCallCount zählen und summaryCallDuration addieren als ein einziger Datensatz. Wenn [FromPhone] und [ToPhone] nicht mehrmals vorkommen, wollte ich alle Spalten als solche auswählen. Ich war in der Lage, Teilabfrage wie unten zu stellen. Aber das gibt nicht alle Spalten zurück, ohne sie in die group by-Klausel aufzunehmen, und es erfüllt auch nicht meine gesamten Kriterien. Jede Hilfe wird sehr geschätzt.

select [FromPhone], 
     MIN([CreationDate]), 
     [ToPhone], 
     marketname, 
     count(*) as TotalCallCount , 
     sum(CallDuration) as TotalCallDuration 
from [dbo].[UserCallData] 
where [CreationDate] >= DATEADD(MONTH, -3, GETDATE()) 
group by [FromPhone],[ToPhone], marketname 
having count([FromPhone]) > 1 and count([ToPhone]) >1 
+0

Wir haben eindeutig Probleme, Ihre Anfrage zu verstehen. Können Sie uns folgendes mitteilen: (a) das "create table" -Skript für die UserCallData-Tabelle, (b) einige Beispieldaten (falls erforderlich anonymisiert) und (c) die erwartete Ausgabe, wenn diese Beispieldaten als Eingabe verwendet werden. Die Daten sollten Zeilen enthalten, die veranschaulichen, wie alle Fälle behandelt werden sollen (also minimal, einige innerhalb der letzten drei Monate, andere nicht). –

Antwort

0

Versuchen zu verwenden ROW_NUMBER()

;with cte as 
(
    select *, ROW_NUMBER() OVER(PARTITION BY FromPhone, ToPhone ORDER BY CreationDate) as RN 
    from UserCallData 
    where CreationDate >= DATEADD(MONTH, -3, GETDATE()) 
), 
cte_totals as 
(
    select C1.FromPhone, C1.ToPhone, COUNT(*) as TotalCallCount, SUM(CallDuration) as TotalCallDuration 
    from cte C1 
    where exists(select * from cte C2 where C1.FromPhone = C2.FromPhone and C1.ToPhone = C2.ToPhone and C2.RN > 1) 
    group by C1.FromPhone, C1.ToPhone 
) 
select C1.*, TotalCallCount, TotalCallDuration 
from cte C1 
    inner join cte_totals C2 on C1.FromPhone = C2.FromPhone and C1.ToPhone = C2.ToPhone 
where C1.RN = 1 

ich Abfrage direkt hier geschrieben, so dass es einige Fehler oder vertippt haben, aber die Grundidee klar sein könnten.

+0

Danke für die Beantwortung meiner Frage! Ich habe Ihre Lösung versucht, aber ich muss diese mehreren Vorkommen in einem Datensatz gruppieren, indem Sie den ersten Datensatz auswählen und die Anzahl der Vorkommen als TotalCallCount zählen und die totalCallDuration summieren. Auch die obige Abfrage gibt nur die letzten 3 Monate Daten zurück. – user7617078

+0

Danke! das scheint zu funktionieren. Diese Abfrage gibt jetzt eindeutige Datensätze zurück, wenn mehrere Vorkommen gefunden wurden. Nun, wie bringe ich andere Datensätze ein, die nicht in die obigen Kriterien fallen (wo es keine Mehrfachvorkommen gibt)? – user7617078

+0

Ich verstehe nicht. Sie möchten in einem Ergebnis alle eindeutigen Datensätze mit Zählern und Summen sehen? – ventik

0

Ich bin nicht ganz sicher, ob ich die Frage verstanden habe, aber wenn ich die folgende haben, was Sie wollen (oder ein nützlicher Ausgangspunkt sein):

SELECT 
     ucd.FromPhone, 
     min(ucd.CreationDate) as MinCreationDate, 
     ucd.ToPhone, 
     ucd.MarketName, 
     count(*) as TotalCallCount, 
     sum(ucd.CallDuration) as TotalCallDuration, 
     case 
      when min(ucd.WebsiteName) = max(ucd.WebsiteName) then min(ucd.WebsiteName) 
      else '* Various' 
     end as WebsiteName, 
     case 
      when min(ucd.ID) = max(ucd.ID) then min(ucd.ID) 
      else '* Various' 
     end as ID, 
     case 
      when min(ucd.UserID) = max(ucd.UserID) then min(ucd.UserID) 
      else '* Various' 
     end as UserID, 
     case 
      when min(ucd.IsAnswered) = max(ucd.IsAnswered) then min(ucd.IsAnswered) 
      else '* Some' 
     end as IsAnswered, 
     case 
      when min(ucd.Source) = max(ucd.Source) then min(ucd.Source) 
      else '* Various' 
     end as Source 
FROM 
    dbo.UserCallData ucd 
WHERE 
    ucd.CreationDate >= DATEADD(MONTH, -3, GETDATE()) 
GROUP BY 
    ucd.FromPhone, 
    ucd.ToPhone, 
    ucd.MarketName 

Wo wir Reihen kollabieren zusammen Wenn alle Zeilen für eine bestimmte Spalte übereinstimmen (also min(Field) = max(Field)), gebe ich den Wert min(Field) zurück (der der gleiche ist wie alle anderen, aber vermeiden Sie Probleme mit zusätzlichen "Gruppieren" -Klauseln, die die anderen Fälle stören würden). Wo sie nicht alle übereinstimmen, bin ich "* something" zurückgekehrt.

Der Code geht davon aus, dass alle Spalten Textspalten sind (Sie haben nicht gesagt), Sie können Konvertierungsfehler erhalten. Es nimmt auch an, dass keines dieser Felder null ist. Sie/wir können den Code anpassen, wenn diese Annahmen nicht korrekt sind. Wenn Sie das nicht selbst tun können, lassen Sie mich über Probleme wissen, ich werde gerne tun, was ich kann.

+0

Basierend auf Ihren Kommentaren zu ventik, möchten Sie möglicherweise die WHERE-Klausel entfernen und fügen Sie die folgenden in GROUP BY hinzu: 'group by case wenn ucd.CreationDate> = DATEADD (MONTH, -3, GETDATE()) dann null else ucd. ID Ende) '.Das setzt voraus, dass ID die Zeile in der Tabelle eindeutig identifiziert. Wenn nicht, brauchst du etwas, das funktioniert. Wenn nichts in der Tabelle verfügbar ist, können Sie 'newid()' verwenden. –

Verwandte Themen