0

I have four tables: families, parents, children, clubs. families have many parents and many children. The children have many clubs memberships.

I would like to create a "view" for fast searching names and email addresses that returns the each of the parents and children, names, email address, along with all an array of all the ids that of all the clubs that their children belong.

Here's what I have so far for the query I would like to be in the view:

 SELECT
  families.id AS family_id,
  'Child' AS searchable_type,
  concat(children.first_name, ' ',children.last_name) AS term,
  '' AS email,
  array_agg(memberships.club_id) AS clubs
FROM children
INNER JOIN families ON children.family_id = families.id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term, email

UNION

SELECT
  families.id AS family_id,
  'Parent' AS searchable_type,
  concat(parents.first_name, ' ',parents.last_name) AS term,
  parents.email AS email,
  array_agg(memberships.club_id) AS clubs

FROM parents
INNER JOIN families ON parents.family_id = families.id
INNER JOIN children ON families.id = children.family_id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, email, term

Question's are:


4

1 回答 1

0

以下是我对最初问题的回答,尽管我怀疑这是性能最高的方法:

  • 我如何摆脱孩子和父母重复的 club_ids?

将 DISTINCT 插入 agg_array 函数

  • 这是一个非常慢的查询。如果它被索引,每次在子级或父级上发生写入时,视图是否会更新?

查询很慢。创建视图非常快。据我目前了解,该视图确实提供了一种方便的搜索方式。该视图不是“真实”表。我认为这就是为什么要确保您正在索引视图的所有搜索词。您没有索引视图本身。

此外,我最终将电子邮件地址移到了它自己的查询中,这样它也成为了一个搜索词。

这是我基于此观点的最后一个查询:

SELECT
  families.id AS family_id,
  'Child' AS searchable_type,
  concat(children.first_name, ' ',children.last_name) AS term,
  array_agg(DISTINCT memberships.club_id) AS clubs
FROM children
INNER JOIN families ON children.family_id = families.id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term

UNION

SELECT
  families.id AS family_id,
  'Parent' AS searchable_type,
  concat(parents.first_name, ' ',parents.last_name) AS term,
  array_agg(DISTINCT memberships.club_id) AS clubs

FROM parents
INNER JOIN families ON parents.family_id = families.id
INNER JOIN children ON families.id = children.family_id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term

UNION

SELECT
  families.id AS family_id,
  'Parent' AS searchable_type,
  email AS term,
  array_agg(DISTINCT memberships.club_id) AS clubs

FROM parents
INNER JOIN families ON parents.family_id = families.id
INNER JOIN children ON families.id = children.family_id
LEFT JOIN memberships ON children.id = memberships.child_id
GROUP BY families.id, term
于 2014-03-07T12:56:54.890 回答