2016-04-21 11 views
0

Ich versuche, eine ausgefallene SQL-Abfrage zu implementieren, habe aber Probleme mit dem Versuch, den Join und die Anzahl auszuführen.SQL REDDIT - Jaccard Ähnlichkeit

Ich habe eine sehr lange Datentabelle:

author | group | id | 

daniel | group1| 118 
adam | group2| 126 
harry | group1| 221 
daniel | group2| 323 
daniel | group2| 122 
daniel | group5| 322 
harry | group1| 222 
harry | group1| 225 

... ...

Ich möchte meine Ausgabe aussehen:

author1 | author2 | intersection | union 

daniel | adam | 2 | 3 
daniel | harry| 2 | 11 
adam | harry| 0 | 10 

wo Kreuzung definiert als die # von Gruppen, wo author1 & author2 gemeinsam haben, und union = # von Gruppen author1 + author - intersection.

denke ich, der richtige Weg, dies zu tun, indem

Tabelle ist eine linke b Tabelle auf a.group == b.group

, aber ich kann nicht herausfinden, teilnehmen, wie die Aggregatzahl zu tun .

Dank enter code here

Antwort

1

„Jumping In“, weil 1) noch keine Antwort nicht sehen, 2) sah damit verbundene Frage des Autors mit BigQuery Tag

Also, theoretisch, unter Abfrage Ihre Aufgabe (mit BigQuery machen würde -samples.reddit.full Tabelle für Beispiele unten):

BigQuery Legacy-SQL:

SELECT 
    a.author AS author1, 
    b.author AS author2, 
    SUM(a.subr = b.subr) AS count_intersection, 
    EXACT_COUNT_DISTINCT(a.subr) + EXACT_COUNT_DISTINCT(b.subr) - SUM(a.subr = b.subr) AS count_union 
FROM 
    (SELECT author, subr FROM [bigquery-samples:reddit.full] GROUP BY 1, 2) AS a 
CROSS JOIN 
    (SELECT author, subr FROM [bigquery-samples:reddit.full] GROUP BY 1, 2) AS b 
WHERE a.author < b.author 
GROUP BY 1, 2 
ORDER BY count_intersection DESC 
LIMIT 100 

BigQuery Standard-SQL:

WITH subrs AS (
    SELECT author, subr 
    FROM `bigquery-samples.reddit.full` 
    GROUP BY 1, 2 
) 
SELECT 
    a.author AS author1, 
    b.author AS author2, 
    COUNTIF(a.subr = b.subr) AS count_intersection, 
    COUNT(DISTINCT a.subr) + COUNT(DISTINCT b.subr) - COUNTIF(a.subr = b.subr) AS count_union 
FROM subrs AS a 
JOIN subrs AS b 
ON a.author < b.author 
GROUP BY 1, 2 
ORDER BY count_intersection DESC 
LIMIT 100 

Wenn Sie sie laufen versuchen, werden Sie wahrscheinlich unter Fehler erhalten

ist ein interner Fehler aufgetreten ist, und die Anforderung nicht

abgeschlossen werden konnte

Der Grund, weil jeder ist von diesen zwei Abfragen erzeugt etwa eine Billion Zeilen als Folge von Join (siehe unten). Es gibt viele Möglichkeiten, dies zu beheben - die unten vorgeschlagene Möglichkeit besteht darin, dies durch Tuning-Anforderungen zu beheben. Müssen Sie wirklich in Algorithmen Lichtautoren einbeziehen mit sagen wir mal ein oder zwei Subreddits? Oder - willst du wirklich Ähnlichkeit zwischen denen finden, die nur sehr wenige Kommentare in bestimmten subreddits haben?

Siehe unten, wie Sie zusätzliche Grenzen Einführung hilft obigen Abfragen bei der Ausführung (Anmerkung: lines ist min Grenzzählwerts der Einträge pro Autor pro subr und subrs ist min Grenze der Anzahl von subr pro Benutzer)

enter image description here

ist Below-Version, das Ergebnis führt tatsächlich w/o jede Art von Versagen:

Standard-SQL

WITH authors AS (
    SELECT author FROM (
    SELECT author, COUNT(1) AS subrs FROM (
     SELECT author, subr, COUNT(1) AS lines 
     FROM `bigquery-samples.reddit.full` 
     GROUP BY 1, 2 
     HAVING lines > 1 
    ) 
    GROUP BY author 
    HAVING subrs > 3 
) 
), 
subrs AS (
    SELECT author, subr 
    FROM `bigquery-samples.reddit.full` 
    WHERE author IN (SELECT author FROM authors) 
    GROUP BY 1, 2 
) 
SELECT 
    a.author AS author1, 
    b.author AS author2, 
    COUNTIF(a.subr = b.subr) AS count_intersection, 
    COUNT(DISTINCT a.subr) + COUNT(DISTINCT b.subr) - COUNTIF(a.subr = b.subr) AS count_union 
FROM subrs AS a JOIN subrs AS b 
ON a.author < b.author 
GROUP BY 1, 2 
ORDER BY count_intersection DESC 
LIMIT 100 

In ähnlicher Weise können Sie Legacy-SQL anpassen, um es

nicht der beste Weg, dies könnte

funktioniert - aber zumindest gibt eine gewisse Hoffnung auf solche Aufgaben innerhalb BigQuery leicht in der Lage sein zu laufen, w/o zu anderen gehen Problemumgehungen