Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是PostgreSQL中视图的正确用法吗?_Postgresql_Database Design - Fatal编程技术网

这是PostgreSQL中视图的正确用法吗?

这是PostgreSQL中视图的正确用法吗?,postgresql,database-design,Postgresql,Database Design,我有两张桌子。一个存储位置,另一个存储这些位置的不同评级(评级可以来自不同的用户,因此一个位置可以有多个评级)。我想有一种方法显示位置名称旁边的平均收视率。我相信我需要用一个视图来创建这个。这是我的桌子: locations有一个name属性和一个id属性,该属性是我的评级表location\u id的外键 ratings有一个location\u id属性、一个user\u id属性和一个属性,用于为进食、阅读、儿童友好型、宠物友好型和可访问性 这是我创建的视图: CREATE VIEW

我有两张桌子。一个存储位置,另一个存储这些位置的不同评级(评级可以来自不同的用户,因此一个位置可以有多个评级)。我想有一种方法显示位置名称旁边的平均收视率。我相信我需要用一个视图来创建这个。这是我的桌子:

  • locations
    有一个
    name
    属性和一个
    id
    属性,该属性是我的
    评级
    location\u id
    的外键
  • ratings
    有一个
    location\u id
    属性、一个
    user\u id
    属性和一个属性,用于为
    进食
    阅读
    儿童友好型
    宠物友好型
    可访问性
这是我创建的视图:

CREATE VIEW v_location_averages AS
SELECT
    r.location_id,
    t.name,
    t.eating,
    t.reading,
    t.child_friendly,
    t.pet_friendly,
    t.accessible,
    (COALESCE(t.eating, 0) + COALESCE(t.reading, 0) + COALESCE(t.child_friendly, 0) + COALESCE(t.pet_friendly, 0) + COALESCE(t.accessible, 0)) / num_nonnulls(t.eating, t.reading, t.child_friendly, t.pet_friendly, t.accessible) AS "overall_rating"
FROM (
    SELECT 
        locations.name,
        location_id, 
        AVG(eating) AS "eating",
        AVG(reading) AS "reading",
        AVG(child_friendly) AS "child_friendly",
        AVG(pet_friendly) AS "pet_friendly",
        AVG(accessible) AS "accessible",
    FROM ratings 
    INNER JOIN locations on ratings.location_id = locations.id
    GROUP BY location_id, locations.name
) t
JOIN ratings r ON r.location_id = t.location_id
GROUP BY r.location_id, t.name, t.eating, t.reading, t.child_friendly, t.pet_friendly, t.accessible;

这是实现我想要的目标的正确方法吗?这是创建该视图的最佳方法吗?(它确实有效,但是否正确?

使用视图确实是一种很好的做法,但在您的情况下,视图可以更简单:

CREATE VIEW v_location_averages AS
SELECT
    t.location_id,
    l.name,
    t.eating,
    t.reading,
    t.child_friendly,
    t.pet_friendly,
    t.accessible,
    (COALESCE(t.eating, 0) + COALESCE(t.reading, 0) + COALESCE(t.child_friendly, 0) + COALESCE(t.pet_friendly, 0) + COALESCE(t.accessible, 0)) / num_nonnulls(t.eating, t.reading, t.child_friendly, t.pet_friendly, t.accessible) AS "overall_rating"
FROM (
    SELECT 
        location_id, 
        AVG(eating) AS "eating",
        AVG(reading) AS "reading",
        AVG(child_friendly) AS "child_friendly",
        AVG(pet_friendly) AS "pet_friendly",
        AVG(accessible) AS "accessible",
    FROM ratings 
    GROUP BY location_id
) t 
INNER JOIN locations l on t.location_id = l.id;

是的,在这里使用视图完全可以。事实上,这比这里无数要求在(父)表中实现此类聚合的请求要好得多。感谢您的快速回复!请问这也是计算平均数的有效方法吗?据推测,每次有人从视图中选择时,它都会计算这些值?这似乎更像是一个问题,请在新帖子中提出一个新问题。如果这是正确的,请给出一个答案。这包括一个明确的规范&DDL。“在平均评分旁边显示位置名称”是否足以让某人带着代码回来做你想做的事情?(使用足够多的单词、句子和对部分示例的引用,以清楚、完整地说出您的意思。在给出业务关系(ship)/关联或表(基础或查询结果)时,请说出其中某一行根据其列值对业务情况的说明。)为什么这可能不正确?PS请不要交叉发布到多个站点。感谢@philipxy的提醒-我以后会这样做(因为这个问题已经得到了回答)