Mysql vrienden van vrienden
Ik heb een vraagje over deze query.
In de tweede select wil ik graag g2.user_name en g2.user_id uit lezen maar als ik die achter f2.naar zet krijg ik de volgende error: 1241 - Operand should contain 1 column(s)
Hoe kan ik dit oplossen om het toch voor elkaar te krijgen?
Wat voor waarde staat er in 'van'?
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
select c.user_name en c.user_id
from TABLE_FRIENDS a
,TABLE_FRIENDS b
,TABLE_USERS c
where a.van = b.naar
and b.naar = c.user_id
and b.naar = $_SESSION['user_id']
from TABLE_FRIENDS a
,TABLE_FRIENDS b
,TABLE_USERS c
where a.van = b.naar
and b.naar = c.user_id
and b.naar = $_SESSION['user_id']
Gewijzigd op 17/12/2010 11:05:53 door John D
Bedankt weer iets geleerd.
Daar zit het id in van de vriend waar hij vrienden van gaat selecteren.
Ik ben er al een tijdje mee aan het stoeien.
Wat hij heel simpel moet doen is vrienden van mijn vrienden selecteren.
Toevoeging op 17/12/2010 12:23:13:
John D Wat ik nu heb is dit hier onder.
Wat alleen nog niet werkt is het overslaan van mensen waar ik ook al mee bevriend ben. Die wil ik namelijk niet weergeven en ik dacht ik doe dat met AND f2.naar!=f1.naar Maar dat wil helaas niet werken. Heeft iemand een idee?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
SELECT g.user_id, g.user_name, g.avatar_default, f2.bid, f2.naar, a.avatar
FROM ".TABLE_FRIENDS." AS f1,
".TABLE_FRIENDS." AS f2,
".TABLE_USERS." AS g
LEFT JOIN
".TABLE_AVATAR." AS a
ON
a.bid = g.avatar_default
WHERE
f2.van=f1.naar AND f1.van='".$_SESSION['user_id']."'
AND f2.naar=g.user_id
AND f2.naar!=f1.van
AND f2.naar!=f1.naar
FROM ".TABLE_FRIENDS." AS f1,
".TABLE_FRIENDS." AS f2,
".TABLE_USERS." AS g
LEFT JOIN
".TABLE_AVATAR." AS a
ON
a.bid = g.avatar_default
WHERE
f2.van=f1.naar AND f1.van='".$_SESSION['user_id']."'
AND f2.naar=g.user_id
AND f2.naar!=f1.van
AND f2.naar!=f1.naar
bump
Wat heb je in die twee dagen geprobeerd?
Ik ben er al een tijdje mee bezig en de manier van John D leek te werken maar de dingen zo als f1.naar!=f2.naar krijg ik niet voor elkaar.
Dat is ook een lastig onderwerp hoor. Ik kwam het tegen toen ik een kabelaansluitadministratie schreef.
Even een stapje terug. Wat zijn "je vrienden"?
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
SELECT van
FROM ".TABLE_FRIENDS."
WHERE naar = ".$_SESSION['user_id']."
UNION
SELECT naar
FROM ".TABLE_FRIENDS."
WHERE van = ".$_SESSION['user_id']."
FROM ".TABLE_FRIENDS."
WHERE naar = ".$_SESSION['user_id']."
UNION
SELECT naar
FROM ".TABLE_FRIENDS."
WHERE van = ".$_SESSION['user_id']."
klopt dat?
Zo selecteer ik mijn vrienden.
Naar is het id van een vriend.
SELECT naar
FROM ".TABLE_FRIENDS."
WHERE van = ".$_SESSION['user_id']."
Helaas kan ik de colom naam niet meer veranderen om dat de site al te groot is.
Ik heb het niet over je kolomnamen. (natuurlijk kun je die veranderen... dat is de vraag toch niet)
Bas Cost Budde dat kan inderdaad, je hoeft je vriend niet te accepteren maar je kan hem wel terug toevoegen. Dan ben je bv met mijn een mutual friend.
Je zegt over je poging "f2.naar!=f1.naar": dat wil helaas niet werken. De schrik van elke helpdeskmedewerker. Krijg je resultaten uit de query, of een foutmelding? Komen er correcte resultaten voor in de query? Komen er foute resultaten voor in de query? Kom je correcte resultaten tekort?
Writer suggestions, rule 12: Be more or less specific. :)
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
SELECT g.user_id, g.user_name, g.avatar_default, f2.bid, f2.naar, a.avatar
FROM ".TABLE_FRIENDS." AS f1,
".TABLE_FRIENDS." AS f2,
".TABLE_USERS." AS g
LEFT JOIN
".TABLE_AVATAR." AS a
ON
a.bid = g.avatar_default
WHERE
f2.naar!=f1.van
AND
f2.naar!=f1.naar
AND
f2.van=f1.naar AND f1.van='".$_SESSION['user_id']."'
AND f2.naar=g.user_id
FROM ".TABLE_FRIENDS." AS f1,
".TABLE_FRIENDS." AS f2,
".TABLE_USERS." AS g
LEFT JOIN
".TABLE_AVATAR." AS a
ON
a.bid = g.avatar_default
WHERE
f2.naar!=f1.van
AND
f2.naar!=f1.naar
AND
f2.van=f1.naar AND f1.van='".$_SESSION['user_id']."'
AND f2.naar=g.user_id
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
SELECT g.user_id, g.user_name,
g.avatar_default, f2.bid, f2.naar,
a.avatar
FROM ".TABLE_FRIENDS." AS f1
INNER JOIN ".TABLE_FRIENDS." AS f2 ON f2.van=f1.naar
INNER JOIN ".TABLE_USERS." AS g ON f2.naar=g.user_id
LEFT JOIN ".TABLE_AVATAR." AS a ON a.bid = g.avatar_default
WHERE f2.naar!=f1.van
AND f2.naar!=f1.naar
AND f1.van=".$_SESSION['user_id']."
g.avatar_default, f2.bid, f2.naar,
a.avatar
FROM ".TABLE_FRIENDS." AS f1
INNER JOIN ".TABLE_FRIENDS." AS f2 ON f2.van=f1.naar
INNER JOIN ".TABLE_USERS." AS g ON f2.naar=g.user_id
LEFT JOIN ".TABLE_AVATAR." AS a ON a.bid = g.avatar_default
WHERE f2.naar!=f1.van
AND f2.naar!=f1.naar
AND f1.van=".$_SESSION['user_id']."
quotes verwijderd om session[userid] omdat dat toch een int moet zijn?
Tussentijds testen. Geeft deze query dezelfde resultaten?
Gebruik dus de eenvoudigste werkende query (van John D??) en voeg daar aan toe:
AND NOT EXISTS (SELECT 1
FROM TABLE_FRIENDS f3
WHERE f3.xxx=f1.xxx
xxx zelf nog even uitzoeken.
Add b ik zal eens kijken.
Ik lees wel een interessant, relevant artikel, dat meer informatie geeft over NOT EXISTS en LEFT JOIN:
http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/
Toevoeging op 19/12/2010 22:41:02:
Derk, niks 'helaas', dat is juist goed. Ik heb namelijk de query alleen syntactisch verbouwd (okee, en de joins expliciet gemaakt).
Neem de velden 'van' en 'naar' uit de tabellen f1 en f2 eens op in de select. Misschien geeft dat aan waar je verwachtingen mislopen.
Je wilt de informatie juist uitsluiten. Een EXISTS of een NOT EXISTS kan fijn via een index unique scan (heet dat ook zo in MySQL?) en is du heel efficient. De enige oplossingen die mijn mijn visie "dure oplossingen" zijn zijn full table scans, dus zolang je geen full table scan toevoegt vind ik elke query okee.
Zal ik al mijn queries eens langslopen op het ongelijk-testen van twee velden... dat is toch de trigger?
Bas Cost Budde bedankt ik heb het allemaal een door gelezen maar wat ik niet snap is dat als ik f2.naar alleen in de select zet ik nog steeds een id krijg die ook al in de f1.naar naar buiten komt terwijl we aan geven f2.naar!=f1.naar. Dat is het grootste probleem.
Bump