【问题标题】:Create a view with repeated combinations of certain columns创建具有某些列的重复组合的视图
【发布时间】:2014-07-15 20:41:47
【问题描述】:

我正在尝试创建一个包含 4 个表中所有数据组合的视图。
这是我的表格的简化布局:

users: 
user_id - a unique id 
name - name of the user 
role - the unique role of the user, which is one of the following

project: 
project_id - a unique id 
project_name - name of the project 

roles:
role - Unique role name.  Currently: (employee, manager, admin)

project_users: 
project_id - the project id from project table 
user_id - the user id from user table 
role - the role of the user associated with user_id

我基本上想创建一个包含project_idroleuser_id 的所有组合的视图,无论是否有某个角色分配给项目的用户。

例如,如果project 表中只有 2 个项目,并且只有 1 个用户分配给项目 1,并且没有用户分配给项目 2,那么视图应该显示如下:

  1. 查看 - project_roles
    • 第 1 行:project_id = 1,角色 = 员工,user_id = 1
    • 第 2 行:project_id = 1,角色 = 经理,user_id = null
    • 第 3 行:项目 id = 1,角色 = 管理员,user_id = null
    • 第 4 行:project_id = 2,角色 = 员工,user_id = null
    • 第 5 行:project_id = 2,角色 = 经理,user_id = null
    • 第 6 行:project_id = 2,角色 = admin,user_id = null

基本上,我将使用此视图返回没有分配给它特定角色的用户的项目。
例如,如果我想获得一个没有分配经理的项目列表,我可以:

SELECT project_id FROM project_roles WHERE user_id IS NULL AND role='manager';

我似乎找不到可以执行此操作的连接查询。到目前为止,我有以下内容:

CREATE VIEW project_roles AS
    SELECT
        pu.project_id,
        pu.user_id,
        r.role
    FROM
        project_users pu
        FULL OUTER JOIN role r ON pu.role = r.role;

但是,它并没有给我想要的视图。 :(

【问题讨论】:

    标签: sql postgresql view


    【解决方案1】:

    我想你想要一个cross join 和一个left outer join

    create view project_roles as
        select p.project_id, r.role, count(pu.user_id)
        from projects p cross join
             roles r left outer join
             project_users pu
             on pu.project_id = p.project_id and pu.role_id = r.role_id
        group by p.project_id, r.role;
    

    需要聚合来获取计数。请注意,如果没有将用户分配给特定的项目/角色组合,这将返回 0。如果你真的想要,你可以把它转换成NULL

    编辑:

    我认为这种修改将适用于公司问题:

    create view  project_roles as
        select p.project_id, r.role, count(pu.user_id)
        from projects p join
             roles r
             on p.company_id = r.company_id left outer join
             project_users pu
             on pu.project_id = p.project_id and pu.role_id = r.role_id
        group by p.project_id, r.role, r.company_id;
    

    我不确定你是否需要 company_id 加入 project_users

    【讨论】:

    • 谢谢戈登!这样可行!然而,我刚刚意识到在我当前的数据库中我忘记提及一个额外的因素。我有不同的公司共享同一个数据库,所以在角色表中实际上有相同名称的重复角色,每个角色分配给不同的公司 ID。项目表也有公司 id 列。我意识到在尝试了您提供的查询示例后,它生成了一个包含数百万行的巨大视图。所以现在我正在尝试更改查询,以便它也将公司 ID 考虑在内。 >
    • 再次感谢戈登~!
    【解决方案2】:

    基本上我会使用这个视图来返回没有 分配给它的特定角色的用户。例如,如果我想 获取没有分配经理的项目列表,我可以:

    SELECT project_id FROM project_roles WHERE user_id IS NULL AND role='manager';
    

    您不需要(不必要的缓慢)视图。只需使用带有NOT EXISTS anti-semi-join 的查询:

    SELECT * FROM project
    WHERE  NOT EXISTS (SELECT 1 FROM project_user WHERE role = 'manager');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-28
      • 1970-01-01
      • 2022-06-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多