复杂的MySQL查询?

时间:2011-07-18 12:51:37

标签: php mysql

我正在为音乐做一个“社交分享”的事情,我只是遇到了一个问题。我的朋友表的结构如下:

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

我的费率表的结构如下:

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

所以我想做的是获得状态为1的3个朋友的随机列表,然后查询每个随机朋友的最近费率的费率表,其中加号= 1.'新近度'(如果你愿意的话)是基于自动增量的ID。

那部分不是真的很难,哈哈。难以理解的是,用户可能在EITHER f1或f2中,因此查询需要包含OR,如果用户在f1中,则需要获取相应的f2,反之亦然。

然后检查他们是否是朋友并且状态= 1,然后由3个随机朋友查询最近费率的费率。然后下载这些数据位,然后写出类似于下面示例的3个字符串

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

如果有人知道如何在PHP / MySQL中编写这样的脚本/查询,我将非常感激!哈哈

谢谢! :)

编辑3 * 在等待回复的同时,我制定了这个部分有效的代码!

<? 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>";

&GT;

2 个答案:

答案 0 :(得分:1)

我认为这可能有助于修改好友查询,使其只返回好友。从你的代码示例中获取部分,这就是我建议的方式:

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
    }

}

修改好友查询的好处是,它总是会在一列中为您提供好友的名字。还有其他方法可以编写好友查询,比如使用UNION,但我认为这个方法很简单,应该可以很好地工作。

我没有测试过上面的代码,所以如果我使用了错误的表名或列名,请随时修复它。此外,虽然上面的代码示例与您的示例保持一致,但您也可以使用JOIN在单个查询中执行上述操作。

希望这有帮助!

答案 1 :(得分:0)

让我们先处理SQL部分。

在你的评论中,你说你正在使用

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

你还说过想要随机抽样。 MySQL具有构造ORDER BY RAND(),因此您的前3个将被随机化。

让我们从里到外解决这个问题。

如果你发出了这个Select语句:

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

然后我想你会从friends表中得到3个随机行,其中status = 1。

(如果朋友被标准化,这将更容易,f1和f2是一个单独的列,另外一列表明f1和f2是如何不同的。就目前而言,有一种计算上昂贵的方法将这两列合并为一列,假设它们是相同的类型,比如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

这将为您提供6个名为$ user的用户名。

解决问题,你需要一个查询来围绕第一个,制作一个subselect语句。要执行下一步,您可以考虑:

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
)

同样,如果你要对friends表进行规范化,这将不会那么复杂。