统计同table中符合条件的其他文档
Count other documents in the same table matching the condition
我有这个查询:
SELECT
id,
(
SELECT COUNT(*)
FROM default t USE KEYS default.id
WHERE t.p_id=default.id
) as children_count
FROM default
WHERE 1
我希望这样:
[
{
"children_count": 5,
"id": "1"
},
...
]
但我明白了:
[
{
"children_count": [
{
"": 0
}
],
"id": "1"
},
...
]
我做错了什么?我用谷歌搜索了这个,但我找不到任何关于 N1QL 中计数子查询的明确解释,因此非常感谢任何指向文档的链接。
更新:
我已经根据@prettyvoid 的回答更新了我的代码。我还创建了最小示例存储桶来演示该问题。
SELECT
id,
(
SELECT COUNT(*) as count
FROM test t USE KEYS "p.id"
WHERE t.p_id=p.id
)[0].count as children_count
FROM test p
WHERE 1
结果如下:
[
{
"children_count": 0,
"id": 1
},
{
"children_count": 0,
"id": 2
},
{
"children_count": 0,
"id": 3
}
]
任何 select
语句都会为您生成一个包含对象的数组,这很正常。如果您想获得预期的结果,那么范围内到数组 [0]
内的计数对象
编辑:下面的查询会做你想要的,不过我不确定是否有更好的方法
SELECT
id,
(
SELECT COUNT(*) as count
FROM default t USE KEYS (SELECT RAW meta().id from default)
WHERE t.p_id=p.id
)[0].count as children_count
FROM default p
请务必注意,在 Couchbase 中,检索文档的最快方法是通过其文档键。使用 GSI 索引是可行的,但速度较慢。与大多数其他数据库一样,最好避免全面扫描。你说你可以使 id
与文档密钥相同,所以我假设是这种情况,这样我就可以在 on keys
子句中使用 p_id
。
是吗o.k。仅列出具有 non-zero 个子项的文档?在这种情况下,您可以将其编写为聚合查询,在其中将每个子项连接到其父项,并按父项 ID 分组(注意我的存储桶称为 default
):
select p.id, count(*) as children_count
from default c join default p on keys c.p_id
group by p.id;
如果您需要包括具有零个子文档的文档,您还需要 UNION
查询来查找这些文档。在这种情况下,我们知道:
select raw array_agg(distinct(p_id)) from default where p_id is not null
会给我们一个父 ID 数组,所以我们可以得到不在列表中的 ID:
select id, 0 as children_count
from default p
where not array_contains(
(select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id);
所以,如果我们 UNION
两个:
(select p.id, count(*) as children_count
from default c join default p on keys c.p_id
group by p.id)
UNION
(select id, 0 as children_count
from default p
where not array_contains(
(select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id));
我们得到所有 ID 及其 children_count 的列表,无论是否为零。如果您想要的不仅仅是 ID,请在每个查询的 select 列表中添加更多字段或“*”。
我有这个查询:
SELECT
id,
(
SELECT COUNT(*)
FROM default t USE KEYS default.id
WHERE t.p_id=default.id
) as children_count
FROM default
WHERE 1
我希望这样:
[
{
"children_count": 5,
"id": "1"
},
...
]
但我明白了:
[
{
"children_count": [
{
"": 0
}
],
"id": "1"
},
...
]
我做错了什么?我用谷歌搜索了这个,但我找不到任何关于 N1QL 中计数子查询的明确解释,因此非常感谢任何指向文档的链接。
更新:
我已经根据@prettyvoid 的回答更新了我的代码。我还创建了最小示例存储桶来演示该问题。
SELECT
id,
(
SELECT COUNT(*) as count
FROM test t USE KEYS "p.id"
WHERE t.p_id=p.id
)[0].count as children_count
FROM test p
WHERE 1
结果如下:
[
{
"children_count": 0,
"id": 1
},
{
"children_count": 0,
"id": 2
},
{
"children_count": 0,
"id": 3
}
]
任何 select
语句都会为您生成一个包含对象的数组,这很正常。如果您想获得预期的结果,那么范围内到数组 [0]
编辑:下面的查询会做你想要的,不过我不确定是否有更好的方法
SELECT
id,
(
SELECT COUNT(*) as count
FROM default t USE KEYS (SELECT RAW meta().id from default)
WHERE t.p_id=p.id
)[0].count as children_count
FROM default p
请务必注意,在 Couchbase 中,检索文档的最快方法是通过其文档键。使用 GSI 索引是可行的,但速度较慢。与大多数其他数据库一样,最好避免全面扫描。你说你可以使 id
与文档密钥相同,所以我假设是这种情况,这样我就可以在 on keys
子句中使用 p_id
。
是吗o.k。仅列出具有 non-zero 个子项的文档?在这种情况下,您可以将其编写为聚合查询,在其中将每个子项连接到其父项,并按父项 ID 分组(注意我的存储桶称为 default
):
select p.id, count(*) as children_count
from default c join default p on keys c.p_id
group by p.id;
如果您需要包括具有零个子文档的文档,您还需要 UNION
查询来查找这些文档。在这种情况下,我们知道:
select raw array_agg(distinct(p_id)) from default where p_id is not null
会给我们一个父 ID 数组,所以我们可以得到不在列表中的 ID:
select id, 0 as children_count
from default p
where not array_contains(
(select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id);
所以,如果我们 UNION
两个:
(select p.id, count(*) as children_count
from default c join default p on keys c.p_id
group by p.id)
UNION
(select id, 0 as children_count
from default p
where not array_contains(
(select raw array_agg(distinct(p_id)) from default where p_id is not null)[0],id));
我们得到所有 ID 及其 children_count 的列表,无论是否为零。如果您想要的不仅仅是 ID,请在每个查询的 select 列表中添加更多字段或“*”。