Результат запроса в виде значения столбца - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть три таблицы:

Уроки:

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

Каждый урок содержит несколько словарей, и каждый словарь может быть включен в несколько уроков.

Как получить вычисляемый и обновленный столбец vocab_count таблицы уроков, когда я добавляю больше строк в таблицу lesson_vocabulary. Возможно ли это, и как бы я go об этом?

Спасибо

Ответы [ 3 ]

0 голосов
/ 09 апреля 2020

Лучше создать представление, которое вычисляет это (и избавиться от столбца в таблице уроков):

select l.*, lv.vocab_count
from lessons l 
  left join (
    select lesson_id, count(*)
    from lesson_vocabulary
    group by lesson_id
  ) as lv(lesson_id, vocab_count) on l.id = lv.lesson_id

Если вы действительно хотите обновлять таблицу уроков каждый раз, когда урок lesson_vocabulary изменения, вы можете запустить инструкцию 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;
0 голосов
/ 09 апреля 2020

Я бы порекомендовал использовать запрос для этой информации:

select l.*,
       (select count(*)
        from lesson_vocabulary lv
        where lv.lesson_id = l.lesson_id
       ) as vocabulary_cnt
from lessons l;

При индексе lesson_vocabulary(lesson_id) это должно быть довольно быстро.

Я рекомендую это через update потому что данные остаются правильными.

Я рекомендую это через триггер, потому что это проще.

Я рекомендую это для подзапроса с агрегацией, потому что это должно быть быстрее, особенно если вы фильтруете в таблице lessons.

0 голосов
/ 09 апреля 2020

Вы можете использовать SQL триггеры, чтобы служить вашей цели. Это будет похоже на mysql после триггера вставки, который обновляет столбец другой таблицы .

Триггер будет выглядеть примерно так. Я использую Oracle SQL, но для любой другой реализации были бы незначительные изменения.

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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...