SQL lekérdezés

Sziasztok,

Kedves SQL guruk az alábbi problémában kérném a segítségeteket: Adott egy példa tábla, melyben blog kommentek vannak. A szerkezet: blog_id, felhasznalo_id, komment, bejegyzes_datum. Ebből a táblázatból kellene blogok kapcsolatát felderítenem (legalább X számú különböző, de közös kommentelőjük van). Tehát olyan lekérdezést kellene futtatnom, aminek az eredménye: blog1, blog2, kozos_komment_szam.

Az a baj, hogy csak egy blogra tudom könnyen megírni a lekérdezést, pl.:
select owner_id, blog_id from bloghu_comment where
( owner_id in (SELECT distinct(owner_id) FROM bloghu_comment where blog_id=3) )
and blog_id != 3

De ez csak a 3. sorszámú blog kapcsolatait adja vissza (ebből természetesen még darabszámot kell kinyerni, de az rendben van). Nekem "egy menetben" kellene az összes.

Előre is köszönöm!

Hozzászólások

Ezzel legeneralod az osszes blog part, mar csak ki kell szamolni a kozos kommentelok szamat es kiszurni azokat, amelyeknel ez nulla:

select b1.blog_id, b2.blog_id from blog_comment b1 join blog_comment b2 on b1.blog_id > b2.blog_id

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"

1. Miért aggódsz? Annyi az adat, amennyi, nem? :) Ha két dolog kapcsolatát kérdezed, nyilván joinolni kell.
2. Nem fog feltétlenül memóriában létrejönni a teljes szorzat. Pl. az első táblán egyesével fog iterálni.
3. Mivel count-ot kérdezel tőle, megfelelő indexek esetén csupán indexből is megválaszolható a kérdés.

--
joco voltam szevasz

Ez esetleg közelebb visz?

CREATE TABLE temp_dist
AS (
select
distinct
blog_id
,owner_id
FROM
bloghu_comment
);

SELECT t1.blog_id
,t2.blog_id
,COUNT(*) no_of_owner
FROM
temp_dist t1
JOIN
temp_dist t2
ON t1.owner_id=t2.owner_id
AND t1.blog_id>t2.blog_id
GROUP BY
t1.blog_id,t2.blog_id
HAVING
no_of_owner > X /*közös kommentelők*/
;

Kb így:


select t1.blog_id as b1,
       t2.blog_id as b2,
       count(1) as cnt
from (
        select blog_id, owner_id
        from bloghu_comment
        group by blog_id, owner_id
     ) t1,
     (
        select blog_id, owner_id
        from bloghu_comment
        group by blog_id, owner_id
     ) t2
where t1.owner_id = t2.owner_id 
  and t1.blog_id < t2.blog_id   
group by t1.blog_id, t2.blog_id
order by t1.blog_id, t2.blog_id; 

Jahh, látom fentebb már volt megoldás...


SELECT c1.blog_id, c2.blog_id, CONCAT( c1.blog_id, c2.blog_id ) AS ignore_me, COUNT( c1.user_id ) AS common_user_cnt
FROM commentz c1 USE INDEX ( IX_blog_user_id ) 
JOIN commentz c2 USE INDEX ( IX_blog_user_id ) ON c1.blog_id != c2.blog_id
WHERE c1.blog_id < c2.blog_id
AND c1.user_id = c2.user_id
GROUP BY ignore_me

A common_user_cnt elvileg megadja a közös usereket (mindkét blogon létezik ugyanaz a user_id).
Olyan sorokat joinol, ahol nem egyezik a blog_id. A bidirekcionális egyezéseket a where első fele eldobja. Az ignore_me alapjan csoportositunk az aggregáthoz. Biztosan van jobb megoldas, de a heti sör mar megvolt.
Lehet profilozni :) Nincs kedvem 5millió sort berandomizálni.