Jag på att lägga in en liten vänner-funktion på en sida jag har och jag har lagt till så att man kan se vilka vänner en person har. Men nu försöker jag få till så att dom vänner som man själv redan är vän med ska markeras annorlunda och här blir det lite problem. Om du kör med den du har så borde du kunna bygga på med joins eller subselects så här: Hmm jag hänger inte med riktigt. Okej, vi tar det i steg. Om jag är "X", så har vi: Jag hänger nog med nu men du har nog missförstått mig. Men jag tar först några frågor angående din kod. Är MyFriends, F, FF osv temporära tabeller eller SELECT-frågor i SELECT-frågorna (så som jag gjorde i min senaste post)? Rent spontant så tänker jag: Ungefär såhär:Exkludera mina egna vänner
Jag kan självklart göra en ny fråga för varje vän och kontrollera, men det känns inte så effektivt.
Tabellerna:
[Users]
ID
[Friends]
UserID
FriendID
Så som jag har gjort det så kommer det att bli dubbla connections mellan vänner, en för att Person A har Person B som vän och så en för att Person B har Person A som vän. Även om det blir dubbelt så mycket data i den tabellen så känns det som att det blir enklare att använda. Eller borde jag alltid bara ha en koppling mellan personerna?
Men som sagt, först och främst vill jag få till så att ens egna vänner markeras annorlunda. Nu får jag fram vännerna genom:
<code>
SELECT Users.ID FROM Users, Friends WHERE Friends.UserID = X AND Users.ID = Friends.FriendID
</code>
där X är personens ID som man vill kolla upp.
/ThomasSv: Exkludera mina egna vänner
Hämta mina vänner:
SELECT FriendID FROM Friends WHERE UserID = X
Hämta mina vänners vänner:
SELECT FriendID FROM Friends WHERE UserID IN (SELECT FriendID FROM Friends WHERE UserID = X)
Det går att skriva om till en join men jag orkar inte tänka just nu. Observera dock att det här kommer kunna ge dubletter, så du borde nog skriva det som
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN (SELECT FriendID FROM Friends WHERE UserID = X)
Och för att ta bort "mina vänner" är det ju egentligen bara att matcha detta mot vännerna
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN (SELECT FriendID FROM Friends WHERE UserID = X) AND FriendID NOT IN (SELECT FriendID FROM Friends WHERE UserID = X)
Eller lite tydligare:
MyFriends = SELECT FriendID FROM Friends WHERE UserID = X
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN MyFriends AND FriendID NOT IN MyFriendsSv:Exkludera mina egna vänner
Ska den sista bli:
<code>
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN (SELECT FriendID FROM Friends WHERE UserID = X) AND FriendID NOT IN (SELECT FriendID FROM Friends WHERE UserID = X)
</code>
Blir inte den koden väldigt tung att köra när två extra SELECT är med?
Hur som helst ser jag inte att den där koden är vad jag är ute efter. När jag hämtar någon annan persons vänlista så vill jag samtidigt ha en variabel som blir 0 eller 1 beroende på om jag redan är vän med den personen. Typ.
/ThomasSv: Exkludera mina egna vänner
SELECT FriendID FROM Friends WHERE UserID = X
För att ta fram mina vänner, right?
Låt säga att Y är min vän - för att ta fram hans vänner så använder vi
SELECT FriendID FROM Friends WHERE UserID = Y
Men eftersom jag kan ha flera vänner så kan vi (om jag skulle ha en tabell "MyFriends", som bara är en lista på mina vänner) skriva:
SELECT FriendID FROM Friends WHERE UserID IN MyFriends
För att få alla mina vänners vänner. Där får vi ju dubletter, om jag har två vänner A och B, och båda är vänner med C, så vi måste använda DISTINCT:
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN MyFriends
MyFriends är ju exakt sanmma sak som "SELECT FriendID FROM Friends WHERE UserID = X", så vi slår ihop det till
SELECT DISTINCT FriendID FROM Friends WHERE UserID IN (SELECT FriendID FROM Friends WHERE UserID = X)
Ok?
Detta kan vi också skriva om till en join, något i stil med:
SELECT FF.FriendID FROM Friends FF
LEFT JOIN Friends F
ON FF.UserID = F.FriendID
WHERE F.UserID = X
Den kan då gå lite fortare (men databasmotorer kan ibland optimera ner det till samma kod ändå). Tipset är att börja med subselectvarianten istället för joinvarianten, eftersom den är enklare.
Okej, så nu har vi en lista på "mina vänners vänner", som inte innehåller dubletter, men eventuellt också "mina vänner". Låt oss kalla "mina vänners vänner" för FF, och "mina vänner" för F.
Är du med på att vi har alla delar vi behöver; "mina vänners vänner" och "mina vänner"?
Exakt hur man sen sätter ihop det till det du vill ha är ju en annan fråga
En variant är nu helt enkelt att ta bort alla som finns i F ur FF:
FF_NOT_F SELECT ID FROM FF WHERE ID NOT IN F
FF_IN_F SELECT ID FROM FF WHERE ID IN F
och sen göra en union:
(SELECT ID, 0 AS MyFriendAlso FROM FF_NOT_F)
UNION
(SELECT ID, 1 AS MyFriendAlso FROM FF_IN_F)
Man kan också tänka sig att detta går att göra med en join, typ
SELECT FF.FriendID, F.FriendID
FF LEFT JOIN F ON FF.FriendID = F.FriendID
Då blir F.FriendID NULL för alla som inte är "mina vänner".Sv:Exkludera mina egna vänner
Nu åter till missförståndet. Jag vill inte ha ut mina vänners vänner som inte är vän med mig, utan en lista över okänd person X's vänner och få indikerat om X's vän Y är vän med mig eller inte.
<code>
SELECT Users.ID, SvartMagi AS IsMyFriend FROM Users, Friends WHERE Friends.UserID = X AND Users.ID = Friends.UserID
</code>
Typ nått sånt. Där SvartMagi är kod innehållandes något som för tillfället känns som just svart magi som är true/false eller 0/1 beroende på om den aktuella Users.ID är vän med mig. X är någon person, vem som helst, som kan vara vän med mig men kan även inte vara vän med mig.
/ThomasSv: Exkludera mina egna vänner
Du returnerar två kolumner: MyFriendsFriendId & MyFriendId. MyFriendsFriendId är id på din väns vänner, MyFriendId är id på dina egna vänner.
Frågan du vill ställa är:
Ge mig alla vänner till min vän, samt gör en LEFT OUTER JOIN med mina egna vänner
Det borde bli rätt
http://en.wikipedia.org/wiki/Join_(SQL)Sv: Exkludera mina egna vänner
<code>
SELECT
a.FriendID,
CASE WHEN b.UserID IS NULL THEN 'Ej Gemensam vän' ELSE 'Gemensam vän' END
FROM Friends a
LEFT OUTER JOIN Friends b ON (a.FriendID = b.FriendID) AND (b.UserID = [mitt ID])
WHERE (a.UserID = [okänds ID]);
</code>
Syntaxen stämmer väl inte riktigt med MySQL, men principen kanske framgår.