Paarungen finden in Tabelle - Kreuzkorrelation?

Paarungen finden in Tabelle - Kreuzkorrelation?

am 05.08.2007 12:26:39 von Sebastian Suchanek

Hallo NGs!

Kurz zur Ausgangssituation meines Problems: Ich habe eine
Datenbanktabelle, die u.a. zwei Spalten mit jeweils einem
Usernamen darin enthält. (Gespeichert als Zeichenkette
(VARCHAR)[1].)
Jetzt möchte ich erfahren, ob es innerhalb dieser Tabelle
Paarungen von Usern gibt, die gehäuft auftreten. Dazu meine
Fragen:

1. Gehe ich recht in der Annahme, daß eine Kreuzkorrelation der
beiden Tabellenspalten zueinander hier das Mittel der Wahl
wäre?

2a) Hat jemand eine Idee, wie man eine solche Kreuzkorrelation
halbwegs effizient in ein SQL-Statement verpackt, bzw. MySQL
überhaupt 'mal dazu überredet, eine solche Kreuzkorrelation
zu berechnen?
2b) Das Ergebnis der SQL-Abfrage sollte im Idealfall auch gleich
die Usernamen mit ausspucken. Als kleines Beispiel:

Daten:

id | user1 | user2
---+-------+-------
1 | Klaus | Bärbel
2 | Klaus | Heinz
3 | Klaus | Bärbel
4 | Max | Petra
5 | Klaus | Bärbel
6 | Max | Petra
7 | Klaus | Anna

Gewünschtes Ergebnis:

user1 | user2
------+------
Klaus | Bärbel
Max | Petra
Klaus | Anna
Klaus | Heinz

2c) Ob dabei die "Reihenfolge" der Spalten beachtet wird, also
ob eine Zeile ("Klaus","Bärbel") als identisch mit
("Bärbel","Klaus") angesehen wird oder nicht, ist zunächst
einmal unerheblich. Allerdings wäre es sozusagen als Bonus
dennoch schön, wenn man darauf Einfluß nehmen könnte.


TIA,

Sebastian

PS: XP de.comp.datenbanken.mysql & de.sci.mathematik, f'up bitte
beim Antworten passend setzen.
_____
Anmerkungen:
[1] Ja, ich weiß, daß das suboptimal ist, aber auf die Form der
"zufließenden" Daten habe ich keinen Einfluß und eine
Normalisierung wäre mit erhöhtem Aufwand verbunden.

--
http://www.baumaschinen-modelle.net
http://www.schwerlast-rhein-main.de

Re: Paarungen finden in Tabelle - Kreuzkorrelation?

am 05.08.2007 13:29:24 von Weinzierl Stefan

Sebastian Suchanek schrieb:
[...]
> Daten:
>
> id | user1 | user2
> ---+-------+-------
> 1 | Klaus | Bärbel
> 2 | Klaus | Heinz
> 3 | Klaus | Bärbel
> 4 | Max | Petra
> 5 | Klaus | Bärbel
> 6 | Max | Petra
> 7 | Klaus | Anna
>
> Gewünschtes Ergebnis:
>
> user1 | user2
> ------+------
> Klaus | Bärbel
> Max | Petra
> Klaus | Anna
> Klaus | Heinz

SELECT COUNT(*) AS Anzahl, user1, user2 FROM daten GROUP BY user1,user2
ORDER BY COUNT(*) DESC

Stefan

Re: Paarungen finden in Tabelle - Kreuzkorrelation?

am 05.08.2007 13:36:34 von dnoeth

Sebastian Suchanek wrote:

> Kurz zur Ausgangssituation meines Problems: Ich habe eine
> Datenbanktabelle, die u.a. zwei Spalten mit jeweils einem
> Usernamen darin enthält. (Gespeichert als Zeichenkette
> (VARCHAR)[1].)
> Jetzt möchte ich erfahren, ob es innerhalb dieser Tabelle
> Paarungen von Usern gibt, die gehäuft auftreten.

Definiere "gehäuft"

> Daten:
>
> id | user1 | user2
> ---+-------+-------
> 1 | Klaus | Bärbel
> 2 | Klaus | Heinz
> 3 | Klaus | Bärbel
> 4 | Max | Petra
> 5 | Klaus | Bärbel
> 6 | Max | Petra
> 7 | Klaus | Anna
>
> Gewünschtes Ergebnis:
>
> user1 | user2
> ------+------
> Klaus | Bärbel
> Max | Petra
> Klaus | Anna
> Klaus | Heinz

select user1, user2
from tab
group by user1, user2
order by count(*) desc

Vielleicht noch ein HAVING count(*) > x?

> 2c) Ob dabei die "Reihenfolge" der Spalten beachtet wird, also
> ob eine Zeile ("Klaus","Bärbel") als identisch mit
> ("Bärbel","Klaus") angesehen wird oder nicht, ist zunächst
> einmal unerheblich. Allerdings wäre es sozusagen als Bonus
> dennoch schön, wenn man darauf Einfluß nehmen könnte.

select u1, u2
from
(select
case when user1 < user2 then user1 else user2 end) as u1,
case when user1 < user2 then user2 else user1 end) as u2
from tab
)
group by u1, u2
order by count(*) desc

Dieter

Re: Paarungen finden in Tabelle - Kreuzkorrelation?

am 05.08.2007 18:47:53 von Weinzierl Stefan

Weinzierl Stefan schrieb:
> Sebastian Suchanek schrieb:
> [...]
>> Daten:
>>
>> id | user1 | user2
>> ---+-------+-------
>> 1 | Klaus | Bärbel
>> 2 | Klaus | Heinz
>> 3 | Klaus | Bärbel
>> 4 | Max | Petra
>> 5 | Klaus | Bärbel
>> 6 | Max | Petra
>> 7 | Klaus | Anna
>>
>> Gewünschtes Ergebnis:
>>
>> user1 | user2
>> ------+------
>> Klaus | Bärbel
>> Max | Petra
>> Klaus | Anna
>> Klaus | Heinz
>
> SELECT COUNT(*) AS Anzahl, user1, user2 FROM daten GROUP BY user1,user2
> ORDER BY COUNT(*) DESC

Oder:
SELECT COUNT(*) AS Anzahl, user1, user2 FROM daten GROUP BY LEAST(user1,
user2), GREATEST(user1, user2) ORDER BY COUNT(*) DESC

Stefan