黑马程序员技术交流社区

标题: 关于如何Sql语句查询里面再嵌套一个查询,求教 [打印本页]

作者: 咖喱猫    时间: 2013-7-20 15:10
标题: 关于如何Sql语句查询里面再嵌套一个查询,求教
本帖最后由 咖喱猫 于 2013-7-20 23:12 编辑

我想查询一个B表(评论表外键UserId,当Id=0时为匿名用户)的数据跟主表A(用户信息表)有一个外键(有一个缺点就是外键里面有一个值为0(代表匿名留言),但是跟在主表里面又没有这个值),我想在不改变数据表结构的前提下 通过PostId(被评论的文章Id)查询B表(有多条数据),当外键UserId不等于零时,再去A表里面查询用户额Name;问题就在这里我没搞明白这个在查询的sql语句中再嵌套一个查询Sql语句;如下代码。(这样写会在第二次查询时报错):求高手帮忙教教Sql语句怎样嵌套查询。(前提,不改变表的结构)
  //查询评论
        public static IList<;PostComments> GetPostCommentsByPostId(int postId)
        {
            IList<;PostComments> pcIList = new List<;PostComments>();
            try
            {
               
                StringBuilder sb = new StringBuilder();
                sb.Append("        SELECT        dbo.Users.Name");
                sb.Append("        FROM            dbo.PostComments INNER JOIN");
                sb.Append("        dbo.Users ON dbo.PostComments.UserId = dbo.Users.UserId where PostId=@postId");
                string sql = "select * from dbo.PostComments where PostId=@postId ";
                SqlParameter[] spr = new SqlParameter[]
                {
                    new SqlParameter("@postId",postId)
                };
                SqlDataReader reader = DBHelper.ExecuteReader(sql, spr);
                while (reader.Read())
                {
                    PostComments pc = new PostComments();
                    pc.CommentId = Convert.ToInt32(reader["CommentId"]);
                    pc.PostId = Convert.ToInt32(reader["PostId"]);
                    pc.UserId = Convert.ToInt32(reader["UserId"]);
                    pc.CommentDate = Convert.ToDateTime(reader["CommentDate"]);
                    pc.Comment = reader["Comment"].ToString();
                    pc.Ip = reader["Ip"].ToString();
                    //判断是否为匿名评论
                    if (pc.UserId != 0)
                    {
                        //不是匿名,就再去查询用户信息表的Name
                        Users u = new Users();
                        u.UserId = Convert.ToInt32(reader["UserId"]);
                        reader.Close();
                        try
                        {
                            //此处报错
                            SqlDataReader reader1 = DBHelper.ExecuteReader(sb.ToString(), spr);
                            while (reader1.Read())
                            {
                                   u.Name=reader["Name"].ToString();
                            }
                            reader1.Close();
                        }
                        catch (Exception)
                        {
                        }
                        pc.user = u;
                    }
                    
                    pcIList.Add(pc);
                }
                reader.Close();
            }
            catch (Exception)
            {
            }
            finally
            {
                DBHelper.Close();
            }
            return pcIList;
作者: changvh    时间: 2013-7-20 16:44
那你里面的查询只需要select name from 用户表 where id = 评论表中的userid不就行了吗?干嘛还要连接查询呢?
作者: 咖喱猫    时间: 2013-7-20 20:52
changvh 发表于 2013-7-20 16:44
那你里面的查询只需要select name from 用户表 where id = 评论表中的userid不就行了吗?干嘛还要连接查询 ...

那样只能查到有限数据,匿名用户都查不到了。
作者: 咖喱猫    时间: 2013-7-20 21:43
这道题是我笨了,其实用一个左联接就可以解决了。sql语句如下:

                SELECT        dbo.PostComments.CommentId, dbo.PostComments.UserId,dbo.PostComments.PostId ,
                                dbo.PostComments.CommentDate, dbo.PostComments.Comment, dbo.PostComments.Ip, dbo.Users.Name
                FROM            dbo.PostComments Left outer JOIN
                dbo.Users ON dbo.PostComments.UserId = dbo.Users.UserId where PostId=@postId
作者: 于驭龙    时间: 2013-7-20 22:47
灵活运用SQL自带的视图模式
利用需要的列单筛选功能  里面写判断就行了
SQL视图会帮你实现你想要的结果 产生自动SQL语句..
这样比较直观..
作者: changvh    时间: 2013-7-21 08:22
咖喱猫 发表于 2013-7-20 20:52
那样只能查到有限数据,匿名用户都查不到了。

你的外层循环不是已经得到评论了嘛,然后判断userid是否为0,如果不为0,去查询用户的信息,直接根据userid不能查到用户信息吗?我不明白,除非你是要一句SQL得到结果,而不是两次查询




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2