0

Ich habe ein System, das SERPs sammelt (Suchmaschinenergebnisse) und speichert sie in der Datenbank. Ich benutze MS SQL 2008 R2.SQL finde alle Gruppen mit mindestens N passenden Elementen

Für jedes angegebene Schlüsselwort gibt es eine SERP-Ergebnisgruppe, die 10 SERP-Elemente enthält.

Keyword -> 
    SERP Group -> 
     - SERP item 
     - SERP item 
     - ... (3-10) 

Entities

public class SerpResultsGroup 
{ 
    public SerpResultsGroup() 
    { 
     SerpResults = new List<SerpResult>(); 
    } 

    public int Id { get; set; } 
    public int KeywordId { get; set; } 
    public Keyword Keyword { get; set; } 

    public ICollection<SerpResult> SerpResults { get; set; } 
} 

public class SerpResult 
{ 
    public int Id { get; set; } 
    public int Position { get; set; } 
    public string Url { get; set; } 

    public int SerpResultsGroupId { get; set; } 
    public SerpResultsGroup SerpResultsGroup { get; set; } 
} 

DB-Schema pic

Jetzt muss ich alle SERP-Gruppen (oder SERP Artikel) kombinieren und solche Gruppen zu finden, wo mindestens N (3) SERP-Artikel sind identisch.

Hier ist ein Bild zur Veranschaulichung der Logik. Grouping algorithm, illustration. Das Bild zeigt, wie verwandte Gruppen übereinstimmen. Der Einfachheit halber gibt es nur 3 Gruppen im Bild, aber in Wirklichkeit könnte es N Gruppen von SERP-Elementen in der Datenbank geben.

Say i eine Gruppe/keyword (group = Schlüsselwort) haben, und ich will alle passenden Gruppen finden, die von einer gegebenen Gruppe mit URLs mindestens 3 (N) haben, übereinstimmt. Diese Gruppen sollten außerdem mindestens 3 (N) passende URLs haben.

Gleiche Kriterien, aber jetzt haben wir eine Startgruppe nicht und wir wollen Gruppe alle Gruppen gegeneinander an.

Wie könnte ich diese Aufgabe erreichen? Muss ich CROSS JOIN verwenden?

aktualisiert

folgende Abfrage scheint mit der ID 11, die eine Reihe von passenden Gruppen für eine bestimmte Gruppe zurückzukehren, aber es überprüft nicht, dass jede Gruppe von zurück Satz gegeneinander abgestimmt ist.

SELECT sr.SerpResultsGroupId, sr1.SerpResultsGroupId 
    FROM SerpResults sr 
    INNER JOIN SerpResults sr1 ON sr.Url = sr1.Url 
    WHERE sr.SerpResultsGroupId != sr1.SerpResultsGroupId 
    AND sr.SerpResultsGroupId = 11 
    GROUP BY sr.SerpResultsGroupId, sr1.SerpResultsGroupId 
    HAVING COUNT(sr1.SerpResultsGroupId) >= 3 
+1

Ihre Darstellung macht keinen Sinn (zumindest für mich). Bearbeiten Sie Ihre Frage und fügen Sie Beispieldaten und gewünschte Ergebnisse in die Frage ein. –

+0

** (1) ** Welche Datenbank benutzen Sie? ** (2) ** Wie soll das Ergebnis aussehen? –

+0

@GordonLinoff, ich habe die Frage aktualisiert.Sieht es besser aus? –

Antwort

0

vereinfachte Lösung für Anwendungsfall von 3 gemeinsamen Elemente. Ähnliche Gruppen haben die gleichen rnk.

select   t.* 

from   (select count (*) over (partition by s1.SERP_item,s2.SERP_item,s3.SERP_item) as cnt 
         ,rank () over (order by  s1.SERP_item,s2.SERP_item,s3.SERP_item) as rnk 

         ,s1.SERP_Group 
         ,s1.SERP_item as SERP_item1 
         ,s2.SERP_item as SERP_item2 
         ,s3.SERP_item as SERP_item3 

       from   SERP as s1 

         join SERP as s2 

         on  s2.SERP_Group = s1.SERP_Group 
          and s2.SERP_item > s1.SERP_item 

         join SERP as s3 

         on  s3.SERP_Group = s2.SERP_Group 
          and s3.SERP_item > s2.SERP_item 
       ) t 

where  t.cnt > 1 

order by t.rnk 
; 

cnt rnk SERP_Group SERP_item1 SERP_item2 SERP_item3 
--- --- ---------- ---------- ---------- ---------- 
2 30 139   4   17   19 
2 30 744   4   17   19 
4 36 372   4   31   33 
4 36 375   4   31   33 
4 36 391   4   31   33 
4 36 408   4   31   33 

generische Lösung für n gemeinsame Elemente. Ähnliche Gruppen haben die gleichen rnk.

with  t (SERP_Group,SERP_item,n,SERP_items) 
      as 
      (
       select SERP_Group,SERP_item,1 as n,cast (SERP_item as varchar(max)) 
       from SERP 

       union all 

       select s.SERP_Group,s.SERP_item,t.n+1,SERP_items + ',' + cast (s.SERP_item as varchar(max)) 

       from   t 
         join SERP s 
         on  s.SERP_Group = t.SERP_Group 
          and s.SERP_item > t.SERP_item 
          and t.n   < 3 
      ) 

select  cnt 
      ,rnk 
      ,SERP_Group 
      ,SERP_items 

from  (select   t.* 
          ,rank () over (order by  SERP_items) as rnk 
          ,count (*) over (partition by SERP_items) as cnt 

      from   t 

      where   t.n = 3 
      ) t 

where  t.cnt > 1 

order by t.rnk 
; 

cnt rnk SERP_Group SERP_items 
--- --- ---------- ---------- 
2 107 139   4,17,19   
2 107 744   4,17,19   
4 113 372   4,17,19   
4 113 375   4,31,33   
4 113 391   4,31,33   
4 113 408   4,31,33  
+0

Danke! Ich werde versuchen, dies gegen Live-Daten laufen zu lassen und die Ergebnisse zu veröffentlichen. –

+0

@AndreyMamon, überprüfen Sie bitte die aktualisierte Antwort. –

+0

Ich bin ein wenig verwirrt, wie die Abfragen an meine Datenbankschema anzupassen. Ich habe zwei Tabellen: SerpResultsGroup und SerpResults. –

1

Verwenden Group by und Having Klausel

Group by SERP_Group,SERP_item 
Having count(1) >= 3 
+0

Ich muss Gruppen miteinander vergleichen, einfache Gruppierung wird nicht funktionieren, denke ich. Ich habe die Frage mit zusätzlichen Informationen aktualisiert. –

Verwandte Themen