当前位置: 首页 > 面试题库 >

加入多对多关系

谷永贞
2023-03-14
问题内容

我有三个表:应用程序,权限和applications_permissions

|------------|   |------------------------|   |-----------|
|applications|   |applications_permissions|   |permissions|
|------------|   |------------------------|   |-----------|
| id         | <-| application_id         |   | id        |
| price      |   | permission_id          |-> | name      |
|------------|   |------------------------|   |-----------|

对于应用程序,有两类:免费和商业类(价格=‘0’和价格!=‘0’)

现在,我想为每个许可都知道有多少百分比的应用程序引用了它。而这两个类别

自由:

id, percentage
1 , 20.0230
2 ,  0.0000
3 ,  0.0312
...

商业的:

id, percentage
1 , 18.0460
2 ,  0.0000
3 ,  0.0402
...

我已经计算出以下查询,但其中不包含没有应用程序的权限ID:/

SELECT (SELECT name FROM permissions WHERE id = applications_permissions.permission_id) AS "name",
        100::float * COUNT(*)/(SELECT COUNT(name) FROM applications WHERE price = \'0\') AS "percent"
  FROM applications, applications_permissions
  WHERE applications.id = applications_permissions.application_id 
    AND applications.price = \'0\'
  GROUP BY applications_permissions.permission_id
  ORDER BY percent DESC')

我该怎么做呢?我已经尝试了几个小时了(该查询,其他联接),但这使我难以捉摸:/


问题答案:

简化了。初稿是最优的。
要在一个查询中计算所有内容:

SELECT p.id
     ,(100 * sum((a.price > 0)::int)) / cc.ct AS commercial
     ,(100 * sum((a.price = 0)::int)) / cf.ct AS free
FROM  (SELECT count(*)::float AS ct FROM applications WHERE price > 0) AS cc
     ,(SELECT count(*)::float AS ct FROM applications WHERE price = 0) AS cf
      ,permissions p
LEFT   JOIN applications_permissions ap ON ap.permission_id = p.id
LEFT   JOIN applications a ON a.id = ap.application_id
GROUP  BY 1, cc.ct, cf.ct
ORDER  BY 2 DESC, 3 DESC, 1;

假设您的价格实际上是一个数字列-0而不是'0'

这包括permissions完全没有附加applications的(LEFT JOIN)。

如果可能applications有未附加permissions的列表,则这些列表的总和不会达到100%。

我只进行ct一次总计数(),并将其转换float为子查询中的值。其余的计算可以使用整数算术完成,只有最后一个/ ct将数字转换为浮点数。这是最快,最精确的。

与CTE相同

如果您愿意接受更多新东西:尝试使用CTE(公用表表达式-
WITH查询)

-从PostgreSQL 8.4开始可用。
它更干净,而且可能稍微快一点,因为我都在一个CTE中工作,而且价格便宜GROUP BY-两者都可以通过子查询来完成:

WITH  c AS (
    SELECT sum((a.price > 0)::int) AS cc
          ,sum((a.price = 0)::int) AS cf
    FROM   applications
    ), p AS (
    SELECT id
          ,sum((a.price > 0)::int) AS pc
          ,sum((a.price = 0)::int) AS pf
    FROM   permissions p
    LEFT   JOIN applications_permissions ap ON ap.permission_id = p.id
    LEFT   JOIN applications a ON a.id = ap.application_id
    GROUP  BY 1
    )
SELECT p.id
     ,(100 * pc) / cc::float AS commercial
     ,(100 * pf) / cf::float AS free
FROM   c, p
ORDER  BY 2 DESC, 3 DESC, 1;


 类似资料:
  • 问题内容: 伙计们,我正在努力为我的公司制作一个简单的票证生成系统,以吸引人。目前,我的MSSQL数据库中有一个名为的表,另一个名为的表。 我的应用程序是C#Windows窗体,因此在新的票证生成窗体上,我有许多文本框和一个用于分配工程师的comboBox,由填充。生成票证后,以这种形式输入的所有信息都将与from一起存储。 效果很好,但是后来我的客户要求我添加选项,以便可以在一张票上分配3名工程

  • 基本上,我想知道如果我有topic1和topic2会发生什么,因为topic1可以有N个topic2元素。 Topic1是用户的事件,topic2是该用户的配置。作为第一步,我将通过key匹配它们,从topic2中过滤掉不属于该用户的配置,但我仍然有多个匹配项。我需要向topic2添加更多过滤器来找到精确的匹配项,但我不知道在按key连接之后是否可以这样做。 我读到这个:Kafka Stream和

  • 问题内容: 我目前正在使用ActiveAndroid,并且在过去的几个小时里一直在尝试建立多对多关系,但是我还是无法正常工作。我希望你能帮助我: 我有“学生”和“课程”的模型,一个学生可以有很多课程,而一个课程有很多学生。基本上,这就是我在“ StudentCourse”模型中所拥有的: 现在,我要做的是使用以下代码获取“课程X中的所有学生”: 但是我收到以下错误: java.lang.Class

  • 在本章中,让我们了解和学习多对多的关系。要表示多对多关系,必须创建第三个表(通常称为联接表),将多对多关系分解为两个一对多关系。 为此,我们还需要添加一个联接表。 下面先添加一个表。表的定义如下所示 - 现在创建一个多对多的关系。假设有多个作者在多个项目上工作,反之亦然。 如您所知,我们在中有一个字段,所以为它创建了一个表。但现在不再需要这个字段了。 选择字段,然后按下删除 按钮,将看到以下消息。

  • 我还想知道如何定义每个模型上的关系--你是否需要或者是否可以只在用户上定义关系?