将2个mysql查询合并为1个

时间:2011-09-03 20:47:53

标签: php mysql sql

我无法在此处尝试创建单个mysql查询。

首先,我将向您展示我用于此特定查询的表格的表结构和字段:

users:
- id
- name
- photo_name
- photo_ext

user_attacks:
- id
- level

user_news_feed:
- id
- id_user
- id_status
- id_attack
- id_profile
- id_wall
- the_date

user_status:
- id
- status

user_wall:
- id
- id_user
- id_poster
- post

每当用户发布攻击或状态更新,更新其个人资料或某人墙上的帖子时,它会将相关数据插入其各自的表中,并在user_news_feed表中插入新行。

现在,我想要做的是从数据库中选择最后10个新闻源项。这些新闻Feed项需要从其他表中获取相关数据,只要它们的值不是0.所以如果新闻源是状态更新,则id_status将是user_status表中状态更新的id,并且“ status“将是需要通过左连接选择的数据。希望这是有道理的。

继承我的第一个mysql查询:

$sql = mysql_query("select n.id_user, n.id_status, n.id_attack, n.id_profile, n.id_wall, n.the_date, u.id, u.name, u.photo_name, u.photo_ext, s.status
                    from `user_news_feed` as n
                    left join `users` u on (u.id = n.id_user)
                    left join `user_status` s on (s.id = n.id_status)
                    where n.id_user='".$_GET['id']."'
                    order by n.id desc
                    limit 10
                    ");

现在这很有效,除了1个问题。正如您所看到的,user_wall表包含2个不同用户的ID。 id_user是发布帖子的用户ID,id_poster是发布该帖子的人的用户ID。如果用户在他/她自己的墙上贴墙,则会将其作为状态更新插入到数据库中,而不是更新到user_status表中。

所以我在第一个查询的while循环中有一个条件语句,其中有另一个sql查询。这是while循环和第二个sql查询的完整代码:

while ($row = mysql_fetch_assoc($sql))
{
    if ($row['id_wall'] != 0)
    {
        $sql_u = mysql_query("select u.id, u.name, u.photo_name, u.photo_ext, w.post
                              from `user_wall` as w
                              left join `users` u on (u.id = w.id_poster)
                              where w.id='".$row['id_wall']."'
                              ");

        while ($row_u = mysql_fetch_assoc($sql_u))
        {
            $row['photo_name'] = $row_u['photo_name'];
            $row['photo_ext'] = $row_u['photo_ext'];
            $row['id_user'] = $row_u['id'];
            $row['name'] = $row_u['name'];
            $content = $row_u['post'];
        }
    }
    else
    {
        if ($row['id_status'] != 0)
            $content = $row['status'];
        else if ($row['id_attack'] != 0)
            $content = '<i>Had an attack</i>';
        else if ($row['id_profile'] != 0)
            $content = '<i>Updated profile</i>';
    }

    echo '<li'.(($count == $total_count) ? ' class="last"' : '').'>';

    echo '<img src="images/profile/'.$row['photo_name'].'_thumb.'.$row['photo_ext'].'" alt="" />';

    echo '<div class="content">';
    echo '<b><a href="profile.php?id='.$row['id_user'].'">'.$row['name'].'</a></b>';
    echo '<span>'.$content.'</span>';
    echo '<small>'.date('F j, Y \a\t g:ia', $row['the_date']).'</small>';
    echo '</div>';

    echo '<div style="clear: both;"></div>';

    echo '</li>';
}

我希望我在这里尝试做的事情是有道理的。所以基本上我想把两个sql查询($ sql和$ sql_u)组合成一个查询,所以当user_news_feed项目是一个墙贴时,我不必每次都查询数据库。

任何帮助将不胜感激,如果这令人困惑,我道歉。

2 个答案:

答案 0 :(得分:2)

SELECT n.id_user, n.id_status, n.id_attack, n.id_profile, n.id_wall, n.the_date,
       u.id, u.name, u.photo_name, u.photo_ext, s.status,
       w.id AS wall_user_id, w.name AS wall_user_name,
       w.photo_name AS wall_user_photo_name,
       w.photo_ext  AS wall_user_photo_ext,
       w.post
  FROM user_news_feed AS n
  LEFT JOIN users AS u ON (u.id = n.id_user)
  LEFT JOIN user_status s ON (s.id = n.id_status)
  LEFT JOIN (SELECT a.id AS id_wall, b.id, b.name, b.photo_name, b.photo_ext, a.post
               FROM user_wall  AS a
               LEFT JOIN users AS b ON (b.id = a.id_poster)
            ) AS w ON w.id_wall = n.id_wall
 WHERE n.id_user = ?
 ORDER BY n.id desc
 LIMIT 10

'?'是一个占位符,您可以在其中提供$_GET['id']的值。

基本上,这会为主查询添加一个额外的外部联接(以及一些额外的列,如果新闻订阅源事件不是墙发布,它将为NULL),但外部联接本身是外部联接的结果

答案 1 :(得分:0)

再次回来;)

无论如何,忘记在我看来合并查询。

你应该做的是做第一个查询,循环遍历所有结果并将所有“id_wall”存储在一个单独的数组中......然后,不是每个“id_wall”执行单独的查询,而是执行此操作:< / p>

$wallids = array();
while ($row = mysql_fetch_assoc($sql)) 
{ 
    $wallids[] = $row['id_wall'];
    // also store the row wherever you want
}

$sql_u = mysql_query("select u.id, u.name, u.photo_name, u.photo_ext, w.post    
                      from `user_wall` as w    
                      left join `users` u on (u.id = w.id_poster)    
                      where w.id IN ('".implode(',', $wallids) ."')    
                      ");

$ wallids是一个包含所有“id_wall”的数组。所以现在你总共有2个查询。