选择每个父母记录的儿童记录数量

发布于 2025-02-03 06:04:59 字数 1909 浏览 4 评论 0原文

这就是我所拥有的:

Table: parent

| id | name |
| -- | ---- |
|  1 | foo  |
|  2 | bar  |
|  3 | baz  |

Table: child

| id | parent_id | type_id |
| -- | --------- | ------- |
|  1 |         2 |       2 |
|  2 |         2 |       2 |
|  3 |      NULL |       2 |
|  4 |         1 |       1 |
|  5 |      NULL |       2 |
|  6 |      NULL |       1 |
|  7 |         1 |       2 |
|  8 |         3 |       1 |

我想选择所有父记录,以及每个父录记录的孩子的数量:

| id | name | type_2_count |
| -- | ---- | ------------ |
|  1 | foo  |            1 |
|  2 | bar  |            2 |
|  3 | baz  |            0 |

我尝试了这一点:

SELECT p.id, name, COUNT(c.id) type_2_count
FROM parent p LEFT JOIN child c ON c.parent_id = p.id
WHERE c.type_id = 2
GROUP BY p.id;

| id | name | type_2_count |
| -- | ---- | ------------ |
|  2 | bar  |            2 |
|  1 | foo  |            1 |

但是它缺少第三个记录。

然后:

SELECT p.id, name, t.cnt type_2_count
FROM parent p LEFT JOIN (
  SELECT parent_id, COUNT(*) as cnt
  FROM child
  WHERE type_id = 2
  GROUP BY parent_id
) t ON t.parent_id = p.id;

| id | name | type_2_count |
| -- | ---- | ------------ |
|  1 | foo  |            1 |
|  2 | bar  |            2 |
|  3 | baz  |         NULL |

但是type_2_countnull而不是0对于第三个记录。

这是我使用的模式:

CREATE TABLE IF NOT EXISTS parent (
  id INT AUTO_INCREMENT,
  name VARCHAR(45) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO parent VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');

CREATE TABLE IF NOT EXISTS child (
  id INT AUTO_INCREMENT,
  parent_id INT REFERENCES parent(id),
  type_id TINYINT NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO child VALUES (1, 2, 2), (2, 2, 2), (3, NULL, 2), (4, 1, 1), (5, NULL, 2), (6, NULL, 1), (7, 1, 2), (8, 3, 1);

This is what I have:

Table: parent

| id | name |
| -- | ---- |
|  1 | foo  |
|  2 | bar  |
|  3 | baz  |

Table: child

| id | parent_id | type_id |
| -- | --------- | ------- |
|  1 |         2 |       2 |
|  2 |         2 |       2 |
|  3 |      NULL |       2 |
|  4 |         1 |       1 |
|  5 |      NULL |       2 |
|  6 |      NULL |       1 |
|  7 |         1 |       2 |
|  8 |         3 |       1 |

I want to select all the parent records, together with the number of child having type 2 for each parent record:

| id | name | type_2_count |
| -- | ---- | ------------ |
|  1 | foo  |            1 |
|  2 | bar  |            2 |
|  3 | baz  |            0 |

I tried this:

SELECT p.id, name, COUNT(c.id) type_2_count
FROM parent p LEFT JOIN child c ON c.parent_id = p.id
WHERE c.type_id = 2
GROUP BY p.id;

| id | name | type_2_count |
| -- | ---- | ------------ |
|  2 | bar  |            2 |
|  1 | foo  |            1 |

But it's missing the third record.

And this:

SELECT p.id, name, t.cnt type_2_count
FROM parent p LEFT JOIN (
  SELECT parent_id, COUNT(*) as cnt
  FROM child
  WHERE type_id = 2
  GROUP BY parent_id
) t ON t.parent_id = p.id;

| id | name | type_2_count |
| -- | ---- | ------------ |
|  1 | foo  |            1 |
|  2 | bar  |            2 |
|  3 | baz  |         NULL |

But type_2_count is NULL instead of 0 for the third record.

This is the schema I used:

CREATE TABLE IF NOT EXISTS parent (
  id INT AUTO_INCREMENT,
  name VARCHAR(45) NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO parent VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');

CREATE TABLE IF NOT EXISTS child (
  id INT AUTO_INCREMENT,
  parent_id INT REFERENCES parent(id),
  type_id TINYINT NOT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;

INSERT INTO child VALUES (1, 2, 2), (2, 2, 2), (3, NULL, 2), (4, 1, 1), (5, NULL, 2), (6, NULL, 1), (7, 1, 2), (8, 3, 1);

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

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

发布评论

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

评论(1

你丑哭了我 2025-02-10 06:05:00

在您的第一个查询中,您需要的唯一更改是将条件从条款从 on on 子句中移动到 or or 条款:

SELECT p.id, name, COUNT(c.id) type_2_count
FROM parent p LEFT JOIN child c 
ON c.parent_id = p.id AND c.type_id = 2
GROUP BY p.id;

以及在您的第二张查询中使用coalesce() /code>将null转换为0

SELECT p.id, name, 
       COALESCE(t.cnt, 0) type_2_count
FROM parent p LEFT JOIN (
  SELECT parent_id, COUNT(*) as cnt
  FROM child
  WHERE type_id = 2
  GROUP BY parent_id
) t ON t.parent_id = p.id; 

请参阅 demo

In your 1st query the only change you need is to move the condition from the WHERE clause to the ON clause:

SELECT p.id, name, COUNT(c.id) type_2_count
FROM parent p LEFT JOIN child c 
ON c.parent_id = p.id AND c.type_id = 2
GROUP BY p.id;

and in your 2nd query use COALESCE() to turn NULL to 0:

SELECT p.id, name, 
       COALESCE(t.cnt, 0) type_2_count
FROM parent p LEFT JOIN (
  SELECT parent_id, COUNT(*) as cnt
  FROM child
  WHERE type_id = 2
  GROUP BY parent_id
) t ON t.parent_id = p.id; 

See the demo.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文