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

发布于 2024-08-16 09:56:41 字数 842 浏览 9 评论 0原文

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

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

在数据库中,每个帖子包含:id(PK)和parent_id(父帖子的id)。如果帖子本身是父帖子,则其parent_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";

棘手的部分是第一个 id 不知道它应该引用子查询之外的第二个 id。我知道我可以执行 SELECT id AS id_tmp ,然后在子查询中引用它,但是如果我还想返回 id 并保留“id”作为列名,那么我必须执行一个返回的查询我有两列具有相同的数据(这对我来说似乎很混乱)

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

这种混乱的方式工作得很好,但我觉得有机会在这里学习一些东西,所以我想我应该发布这个问题。

How do I specify the parent query field from within a subquery in MySQL?

For Example:
I have written a basic Bulletin Board type program in PHP.

In the database each post contains: id(PK) and parent_id(the id of the parent post). If the post is itself a parent, then its parent_id is set to 0.

I am trying to write a mySQL query that will find every parent post and the number of children that the parent has.

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

The tricky part is that the first id doesn't know that it should be referring to the second id that is outside of the subquery. I know that I can do SELECT id AS id_tmp and then refer to it inside the subquery, but then if I want to also return the id and keep "id" as the column name, then I'd have to do a query that returns me 2 columns with the same data (which seems messy to me)

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

The messy way works fine, but I feel an opportunity to learn something here so I thought I'd post the question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

微暖i 2024-08-23 09:56:41

怎么样:

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

How about:

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

or if you put an alias on the p1.id, you might say:

$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";
夏有森光若流苏 2024-08-23 09:56:41

您可以尝试类似的操作

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

You could try something like this

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

To get back to your example, use the alias of the main table in the sub select

SELECT  pt.id,
        (SELECT COUNT(1) FROM post_table WHERE parent_id = pt.id) 
FROM    post_table pt
WHERE   pt.parent_id = 0
若水微香 2024-08-23 09:56:41

为表指定唯一的名称:

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

Give the tables unique names:

$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";
月亮是我掰弯的 2024-08-23 09:56:41

以下语法适用于 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

The following syntax works in Oracle. Can you test if the same works in MYSQL too?
It is called scalar subquery in Oracle.

You would just need to alias the two tables differently to distinguish between them if you are using the same table twice.

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
红ご颜醉 2024-08-23 09:56:41

谢谢唐。我有一个如下所示的嵌套查询,其中的 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 */
);

因此,我只是在 JOIN 中再次添加了别名 v1 。这使它发挥作用。

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 */
);

希望这对某人有帮助。

Thanks Don. I had a nested query as shown below and a WHERE clause in it wasn't able to determine alias v1. Here is the code which isn't working:

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 */
);

So, I just added the alias v1 again inside the JOIN. Which made it work.

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 */
);

Hope this will be helpful for someone.

夜空下最亮的亮点 2024-08-23 09:56:41

MySQL 8 中子查询中的父查询字段。

我使用嵌套查询根据 tblgamescores 中的用户名选择游戏分数。

SELECT 
    GameScoresID, 
    (SELECT Username FROM tblaccounts WHERE AccountID = FromAccountID) AS FromUsername, 
    (SELECT Username FROM tblaccounts WHERE AccountID = ToAccountID) AS ToUsername,
    (SELECT Username FROM tblaccounts WHERE AccountID = WinAccountID) AS WinUsername,
    (SELECT Username FROM tblaccounts WHERE AccountID = LossAccountID) AS LossUsername,
    FromUserScore,
    ToUserScore 
FROM tblgamescores a 
WHERE FromAccountID = (SELECT AccountID FROM tblaccounts WHERE Username = "MHamzaRajput");

Parent query field within a subquery in MySQL 8.

I'm selecing games scores on the basis of username from tblgamescores using nested query.

SELECT 
    GameScoresID, 
    (SELECT Username FROM tblaccounts WHERE AccountID = FromAccountID) AS FromUsername, 
    (SELECT Username FROM tblaccounts WHERE AccountID = ToAccountID) AS ToUsername,
    (SELECT Username FROM tblaccounts WHERE AccountID = WinAccountID) AS WinUsername,
    (SELECT Username FROM tblaccounts WHERE AccountID = LossAccountID) AS LossUsername,
    FromUserScore,
    ToUserScore 
FROM tblgamescores a 
WHERE FromAccountID = (SELECT AccountID FROM tblaccounts WHERE Username = "MHamzaRajput");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文