2011-07-18 6 views
1

Je travaille sur un genre de «partage social» pour la musique, et j'ai juste rencontré un problème. Ma table d'amis est structuré comme suit:Requête MySQL compliquée?

| id |  f1 | f2 | status | 
---------------------------------------------- 
| 000001 | username1 |username2|  0  | 
| 000002 | username4 |username7|  1  | 

ma table de taux est structuré comme celui-ci:

| id | username | songname | songid | plus | minus | 
---------------------------------------------------- 
|0001| username1| Songname | 000001 | 0001 | 00000 | 
|0002| username3| Song2222 | 000002 | 0000 | 00001 | 

Et ce que je suis en train de faire, est d'obtenir une liste aléatoire de 3 amis où le statut est 1, puis interroger la table des taux pour le taux le plus récent de chaque ami aléatoire où plus = 1. 'Récence' (si vous voulez) est basé sur l'ID qui est auto-incrémental.

Cette partie n'est pas vraiment difficile, lol. Le bit difficile, c'est que l'utilisateur peut être SOIT F1 OU f2, donc la requête doit contenir un OU, et si l'utilisateur est en f1, il devra obtenir le f2 correspondant, et vice versa.

Puis vérifiez s'il s'agit d'amis et de statut = 1, puis interrogez les taux pour les tarifs les plus récents par les 3 amis aléatoires. Ensuite, téléchargez les bits de données, puis d'écrire 3 chaînes semblables à l'exemple ci-dessous

<a href="profile.php?u=username3">username 3</a> +1'd <a href="song.php?id=2">Song2222</a> 

Si quelqu'un veut savoir comment écrire un script/requête comme ceci en PHP/MySQL, je serais très reconnaissant! Haha

Merci! :)

Éditer 3 * En attendant les réponses, j'ai élaboré ce code, qui fonctionne en partie!

<? session_start(); 
$user = $_SESSION['username']; 

mysql_connect("localhost", "xxxxx", "xxxx") or die(mysql_error()); 
mysql_select_db("xxxxxx") or die(mysql_error()); 

$q1data = mysql_query("SELECT * FROM friends WHERE (f1='$user') OR (f2='$user') AND status=1 ORDER BY RAND() LIMIT 1") ; 
    if(mysql_num_rows($q1data)===1) 
      { 
       $q1result = mysql_fetch_assoc($q1data); 
       $q1f1 = $q1result['f1']; 
       $q1f2 = $q1result['f2']; 
        if($q1f1==$user) { 
         $oq2un1 = $q1f2; 
         } 
        if($q1f2==$user) { 
        $oq2un1 = $q1f1; 
        } 
      } 
$q2data = mysql_query("SELECT * FROM friends WHERE (f1='$user') OR (f2='$user') AND status=1 ORDER BY RAND() LIMIT 1") ; 
    if(mysql_num_rows($q2data)===1) 
      { 
       $q2result = mysql_fetch_assoc($q2data); 
       $q2f1 = $q2result['f1']; 
       $q2f2 = $q2result['f2']; 
        if($q2f1==$user) { 
         $oq2un2 = $q2f2; 
         } 
        if($q2f2==$user) { 
        $oq2un2 = $q2f1; 
        } 
      } 
$q3data = mysql_query("SELECT * FROM friends WHERE (f1='$user') OR (f2='$user') AND status=1 ORDER BY RAND() LIMIT 1") ; 
    if(mysql_num_rows($q3data)===1) 
      { 
       $q3result = mysql_fetch_assoc($q3data); 
       $q3f1 = $q3result['f1']; 
       $q3f2 = $q3result['f2']; 
        if($q3f1==$user) { 
         $oq2un3 = $q3f2; 
         } 
        if($q3f2==$user) { 
        $oq2un3 = $q3f1; 
        } 
      } 

/************************************* SECOND SET OF QUERIES ******************************************/ 

$q4data = mysql_query("SELECT * FROM rates WHERE username='$oq2un1' AND plus=1 ORDER BY id LIMIT 1"); 
if(mysql_num_rows($q4data)===1) 
      { 
       $q4result = mysql_fetch_assoc($q4data); 
       $finalusername1 = $q4result['username']; 
       $q4songid = $q4result['song_id']; 
       $q4songname = $q4result['songname']; 
      } 
$q5data = mysql_query("SELECT * FROM rates WHERE username='$oq2un2' AND plus=1 ORDER BY id LIMIT 1"); 
if(mysql_num_rows($q5data)===1) 
      { 
       $q5result = mysql_fetch_assoc($q5data); 
       $finalusername2 = $q5result['username']; 
       $q5songid = $q5result['song_id']; 
       $q5songname = $q5result['songname']; 
      } 
$q6data = mysql_query("SELECT * FROM rates WHERE username='$oq2un3' AND plus=1 ORDER BY id LIMIT 1"); 
if(mysql_num_rows($q6data)===1) 
      { 
       $q3result = mysql_fetch_assoc($q6data); 
       $finalusername3= $q6result['username']; 
       $q6songid = $q6result['song_id']; 
       $q6songname = $q6result['songname']; 
      } 
$socialmuze_string1 = $finalusername1." recently <font color='#00FF00'>+1'd</font> <a href='song?id=".$q4songid."'>".$q4songname."</a><br>"; 
$socialmuze_string2 = $finalusername2." recently <font color='#00FF00'>+1'd</font> <a href='song?id=".$q5songid."'>".$q5songname."</a><br>"; 
$socialmuze_string3 = $finalusername3." recently <font color='#00FF00'>+1'd</font> <a href='song?id=".$q6songid."'>".$q6songname."</a><br>"; 

echo $finalusername1." ".$q4songname."<br>"; 
echo $finalusername2." ".$q5songname."<br>"; 
echo $finalusername3." ".$q6songname."<br>"; 

?>

+1

Salut, @Karan, pourriez-vous s'il vous plaît poster ce que vous avez essayé jusqu'à présent et comment il a échoué? Nous préférons réparer les choses à SO et vous aider à être un meilleur programmeur, pas à construire des choses à partir de zéro. – rajah9

+0

Très bien! Je n'en ai pas trop pour le moment: S Je n'arrive pas vraiment à savoir quoi faire après: S $ user étant f1 ou f2. Edit * En fait, je vais éditer cela à la question –

+0

Nonobstant une solution finale, en construisant votre chaîne avec des chaînes intégrées de variables de session utilisateur pourrait vous laisser WIDE OPEN aux attaques par injection SQL ... regardez en utilisant des paramètres pour vos requêtes. – DRapp

Répondre

0

Soit le travail de la part de SQL premier.

Dans votre commentaire, vous avez dit que vous utilisez

SELECT * FROM friends WHERE (f1='$user') OR (f2='$user') LIMIT 3 

Vous avez également dit que vous vouliez obtenir un échantillon aléatoire. MySQL a la construction ORDER BY RAND() pour que vos 3 premiers soient randomisés.

Voyons cela de l'intérieur.

Si vous avez émis cette instruction Select:

SELECT * FROM friends where status=1 and (f1='$user' OR f2='$user') order by RAND() limit 3 

Je pense que vous obtiendrez 3 lignes au hasard à partir de la table d'amis où l'état = 1.

(Cela serait beaucoup plus facile si les amis étaient normalisés et si f1 et f2 étaient une seule colonne avec une colonne supplémentaire indiquant comment f1 et f2 étaient différents. un, supposant ils sont du même type, disent varchar (13).)

SELECT f1 FROM friends where status=1 and f1='$user' order by RAND() limit 3 
union all 
SELECT f2 FROM friends where status=1 and f2='$user' order by RAND() limit 3 

que vous obtiendrez 6 noms d'utilisateur que l'on appelle l'utilisateur $. En cours de route, vous aurez besoin d'une requête pour entourer la première, en faisant une sous-sélection.Pour ce faire, l'étape suivante, vous pouvez envisager:

SELECT * from rates where username in (
    SELECT f1 FROM friends where status=1 and f1='$user' order by RAND() limit 3 
    union all 
    SELECT f2 FROM friends where status=1 and f2='$user' order by RAND() limit 3 
) 

Encore une fois, ce ne serait pas tout à fait si complexe, si vous deviez normaliser la table d'amis.

+0

Je pensais à une sorte d'append, comme nom d'utilisateur1.username2 et en utilisant les outils de chaîne en PHP pour décoder ce que cela signifiait, mais les amis La requête revient trop souvent pour que cela soit logique: S Quoi qu'il en soit, merci beaucoup pour l'exemple de code! Je vais essayer! :) –

1

Je pense que cela pourrait aider à modifier la requête des amis de sorte qu'elle ne renvoie que les amis. Reprenant des portions de votre exemple de code, voilà comment je vous suggère de le faire:

session_start(); 
$user = $_SESSION['username']; 

// retrieve random 3 friends 
$rsFriends = mysql_query('SELECT `id`, 
     (CASE 
     WHEN `f1` = \'' . mysql_real_escape_string($user) . '\' THEN `f2` 
     WHEN `f2` = \'' . mysql_real_escape_string($user) . '\' THEN `f1` 
     END) AS `friend` 
    FROM `friends` 
    WHERE `status` = 1 
    AND (`f1` = \'' . mysql_real_escape_string($user) . '\' 
     OR `f2` = \'' . mysql_real_escape_string($user) . '\') 
    ORDER BY RAND() 
    LIMIT 3'); 
while ($row = mysql_fetch_assoc($rsFriends)) { 
    // retrieve the most recent rate entry where plus = 1 
    $rsRates = mysql_query('SELECT `id`, `username`, `songname`, `songid`, `plus`, `minus` 
     FROM `rates` 
     WHERE `username` = \'' . mysql_real_escape_string($row['friend']) . '\' 
     AND `plus` = 1 
     ORDER BY `id` DESC 
     LIMIT 1'); 
    while ($row1 = mysql_fetch_assoc($rsRates)) { 
     // $row1 is the array that contains the most recent rate where plus = 1 
    } 

}

L'avantage avec la modification des amis requête est qu'il vous donnera toujours le nom de l'ami une seule colonne. Il y a d'autres façons d'écrire la requête des amis, comme utiliser UNION, mais je pense que celle-ci est simple et devrait fonctionner aussi bien.

Je n'ai pas testé le code ci-dessus, alors n'hésitez pas à le corriger si j'ai utilisé un mauvais nom de table ou de colonne. En outre, bien que l'exemple de code ci-dessus reste dans les lignes de votre exemple, vous pouvez aussi faire ce qui précède dans une seule requête en utilisant JOINs.

Espérons que cela aide!

+0

Merci! Je vais essayer :) –