代码之家  ›  专栏  ›  技术社区  ›  justinl

如何在MySQL的子查询中指定父查询字段?

  •  46
  • justinl  · 技术社区  · 16 年前

    在MySQL中,有没有一种方法可以从子查询中指定父查询字段?

    例如:
    我用PHP编写了一个基本的公告板类型的程序。

    在数据库中,每个日志包含:id(pk)和parent_id(父日志的id)。如果post本身是父级,那么它的父级\u id设置为0。

    我正在尝试编写一个mysql查询,它将查找每个父日志和父日志中的子日志数。

    $query = "SELECT id, (
          SELECT COUNT(1) 
          FROM post_table 
          WHERE parent_id = id
    ) as num_children
    FROM post_table
    WHERE parent_id = 0";
    

    最棘手的是第一个 身份证件 不知道应该指第二个 身份证件 在子查询之外。我知道我可以选择i d作为i d_tmp,然后在子查询中引用它,但是如果我还想返回i d并保留“i d”作为列名,那么我必须执行一个返回两列相同数据的查询(这对我来说似乎很混乱)。

    $query = "SELECT id, id AS id_tmp, 
                (SELECT COUNT(1)
                FROM post_table
                WHERE parent_id = id_tmp) as num_children
             FROM post_table
             WHERE parent_id = 0";
    

    这种混乱的方式很好用,但我觉得有机会在这里学到一些东西,所以我想我会把问题贴出来。

    5 回复  |  直到 10 年前
        1
  •  67
  •   Don    11 年前

    怎么样:

    $query = "SELECT p1.id, 
                     (SELECT COUNT(1) 
                        FROM post_table p2 
                       WHERE p2.parent_id = p1.id) as num_children
                FROM post_table p1
               WHERE p1.parent_id = 0";
    

    或者,如果在p1.id上添加别名,可以说:

    $query = "SELECT p1.id as p1_id, 
                     (SELECT COUNT(1) 
                        FROM post_table p2 
                       WHERE p2.parent_id = p1.id) as num_children
                FROM post_table p1
               WHERE p1.parent_id = 0";
    
        2
  •  4
  •   Adriaan Stander    16 年前

    你可以试试这个

    SELECT  pt.id,
            CountTable.Cnt
    FROM    post_table pt LEFT JOIN
            (
                SELECT  parent_id,
                        COUNT(1) Cnt
                FROM    post_table
                WHERE   parent_id <> 0
                GROUP BY parent_id
            ) CountTable ON pt.id = CountTable.parent_id
    WHERE   pt.parent_id = 0
    

    要回到您的示例,请使用 别名 子选择中的主表

    SELECT  pt.id,
            (SELECT COUNT(1) FROM post_table WHERE parent_id = pt.id) 
    FROM    post_table pt
    WHERE   pt.parent_id = 0
    
        3
  •  2
  •   Tatu Ulmanen    16 年前

    为表指定唯一的名称:

    $query = "SELECT a.id, (SELECT COUNT(1) FROM post_table b WHERE parent_id = a.id) as num_children FROM post_table a WHERE a.parent_id = 0";
    
        4
  •  0
  •   Rajesh Chamarthi    16 年前

    以下语法适用于Oracle。你能测试一下MySQL中是否同样有效吗? 在Oracle中称为标量子查询。

    如果两次使用同一个表,则只需对两个表进行不同的别名,以区分它们。

    sql> select empno,
      2         (select dname from dept where deptno = emp.deptno) dname
      3    from emp 
      4    where empno = 7369;
    
         EMPNO DNAME
    ---------- --------------
          7369 RESEARCH
    
    sql> select parent.empno,
      2         (select mgr from emp where empno = parent.empno) mgr
      3    from emp parent
      4    where empno = 7876;
    
         EMPNO        MGR
    ---------- ----------
          7876       7788
    
        5
  •  0
  •   Mr_Green    10 年前

    谢谢,唐。我有一个嵌套的查询,如下所示, WHERE 它中的子句无法确定别名 v1 . 以下是不起作用的代码:

    Select 
        teamid,
        teamname
    FROM
        team as t1
    INNER JOIN (
        SELECT 
            venue_id, 
            venue_scores, 
            venue_name 
        FROM venue 
        WHERE venue_scores = (
            SELECT 
                MAX(venue_scores) 
            FROM venue as v2 
            WHERE v2.venue_id = v1.venue_id      /* this where clause wasn't working */
        ) as v1    /* v1 alias already present here */
    );
    

    所以,我刚刚添加了别名 V1 再次在里面 JOIN . 这使它成功了。

    Select 
        teamid,
        teamname
    FROM
        team as t1
    INNER JOIN (
        SELECT 
            venue_id, 
            venue_scores, 
            venue_name 
        FROM venue as v1              /* added alias v1 here again */
        WHERE venue_scores = (
            SELECT 
                MAX(venue_scores) 
            FROM venue as v2 
            WHERE v2.venue_id = v1.venue_id   /* Now this works!! */
        ) as v1     /* v1 alias already present here */
    );
    

    希望这对某人有帮助。