Sql 查询结果作为列值
我有三张桌子: 经验教训:Sql 查询结果作为列值,sql,postgresql,Sql,Postgresql,我有三张桌子: 经验教训: CREATE TABLE lessons ( id SERIAL PRIMARY KEY, title text NOT NULL, description text NOT NULL, vocab_count integer NOT NULL ); +----+------------+------------------+-------------+ | id | title | description | v
CREATE TABLE lessons (
id SERIAL PRIMARY KEY,
title text NOT NULL,
description text NOT NULL,
vocab_count integer NOT NULL
);
+----+------------+------------------+-------------+
| id | title | description | vocab_count |
+----+------------+------------------+-------------+
| 1 | lesson_one | this is a lesson | 3 |
| 2 | lesson_two | another lesson | 2 |
+----+------------+------------------+-------------+
第十一课词汇:
CREATE TABLE lesson_vocabulary (
lesson_id integer REFERENCES lessons(id),
vocabulary_id integer REFERENCES vocabulary(id)
);
+-----------+---------------+
| lesson_id | vocabulary_id |
+-----------+---------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 2 | 4 |
+-----------+---------------+
CREATE TABLE vocabulary (
id integer PRIMARY KEY,
hiragana text NOT NULL,
reading text NOT NULL,
meaning text[] NOT NULL
);
词汇:
CREATE TABLE lesson_vocabulary (
lesson_id integer REFERENCES lessons(id),
vocabulary_id integer REFERENCES vocabulary(id)
);
+-----------+---------------+
| lesson_id | vocabulary_id |
+-----------+---------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 2 | 4 |
+-----------+---------------+
CREATE TABLE vocabulary (
id integer PRIMARY KEY,
hiragana text NOT NULL,
reading text NOT NULL,
meaning text[] NOT NULL
);
每节课包含多个词汇,每个词汇可以包含在多节课中
当我向lesson_词汇表添加更多行时,如何计算和更新lessons表的vocab_count列。这可能吗?我该怎么做
谢谢您可以使用SQL触发器来达到您的目的。这将类似于 触发器看起来有点像这样。我正在使用oraclesql,但对于任何其他实现都会有一些小的调整
CREATE TRIGGER vocab_trigger
AFTER INSERT ON lesson_vocabulary
FOR EACH ROW
begin
for lesson_cur in (select LESSON_ID, COUNT(VOCABULARY_ID) voc_cnt from LESSON_VOCABULARY group by LESSON_ID) LOOP
update LESSONS
set VOCAB_COUNT = LESSON_CUR.VOC_CNT
where id = LESSON_CUR.LESSON_ID;
end loop;
END;
最好创建一个计算该值的视图(并去掉lessons表中的列):
如果确实希望在每次更改lesson_词汇表时更新lessons表,则可以在触发器中运行如下update语句:
update lessons l
set vocab_count = t.cnt
from (
select lesson_id, count(*) as cnt
from lesson_vocabulary
group by lesson_id
) t
where t.lesson_id = l.id;
我建议使用查询来查询此信息:
select l.*,
(select count(*)
from lesson_vocabulary lv
where lv.lesson_id = l.lesson_id
) as vocabulary_cnt
from lessons l;
在lesson\u词汇表(lesson\u id)
上有一个索引,这应该非常快
我建议您在更新时使用此选项,因为数据仍然正确
我建议不要使用触发器,因为它更简单
我建议使用聚合子查询,因为它应该更快,特别是当您在lessons
表上进行筛选时。您需要一个触发器。但一般来说,您不应该将信息存储在可以从现有数据派生的关系数据库中。为什么不创建一个返回该计数的视图呢?好的,我明白你的意思。所以我根本不应该为此创建一个列,而只是创建一个视图来显示每节课的所有链接词汇表?另外,如果我想在页面上显示包括每节课词汇表计数在内的课程信息。我会先获取lessons表中的所有行,然后对每一行运行一个查询来计算我自己的词汇量吗?有没有一种方法可以一步完成呢?根据我的经验,对派生表的连接并不是很慢,而且过滤条件很容易被Postgres推下。但是,如果对许多行执行此操作,则相关子查询的速度往往较慢。它必须处理的行越多(来自课程表),差异就越大gets@a_horse_with_no_name . . . 如果正在选择第一个表中的所有行,则不会。但是,如果行在外部查询中被过滤,那么我认为Postgres不会将过滤推送到聚合子查询,因此聚合要做更多的工作