【发布时间】:2013-11-11 20:51:14
【问题描述】:
我有一个评论系统,用户可以在其中评论帖子,然后用户可以回复那些顶级 cmets。这就是嵌套的扩展:用户无法回复回复。
顶级 cmets 和回复位于同一个表中。它们几乎完全相同。顶级 cmets 有一个post_id,回复有一个parent_id。我在表上使用了一个约束来确保这些列中的一列对每一行都有一个值。
CREATE TABLE comments (
id integer NOT NULL,
post_id integer,
author_id integer NOT NULL,
body text,
created_at timestamp without time zone,
updated_at timestamp without time zone,
parent_id integer,
CONSTRAINT must_have_media_item_xor_parent CHECK ((((media_item_id IS NULL) AND (parent_id IS NOT NULL)) OR ((media_item_id IS NOT NULL) AND (parent_id IS NULL))))
);
现在我想统计特定帖子上的所有 cmets,包括回复。查询
SELECT count(*)
FROM comments
WHERE comments.post_id = 123
告诉我#123 后有多少顶级 cmets。查询
SELECT count(*)
FROM comments
JOIN comments AS replies ON replies.parent_id = comments.id
WHERE comments.post_id = 123
告诉我有多少回复。我可以同时做这两件事并将它们加在一起,但这听起来很重,而且希望没有必要。
避免第二个查询中的自联接的一种解决方案是在回复中也设置post_id,使值非规范化。然后第一个查询将计算所有这些。如果我这样做,我真的很想在数据库中进行某种一致性检查,以确保我做对了。
当设置parent_id 时,有没有办法让Postgres 将post_id 的值限制为其父级的值?普通约束似乎只能查看一行。
或者,有没有其他好方法一举数出所有 cmets?
【问题讨论】:
-
我发布了未经测试的回复。如果您提供示例数据,我将创建
SQL Fiddle,以便您进行测试。 -
这样的问题需要提供相关的表定义(就像你在psql中使用
\d tbl一样。另外,你的Postgres版本。还有一些测试用例的示例数据会很好。
标签: sql postgresql count