【问题标题】:SQL GroupBy to select % of valuesSQL Group By 以选择值的百分比
【发布时间】:2013-11-25 11:19:55
【问题描述】:

我正在使用 Access(我知道 JET SQL 与 T-SQL 不同,但如果您在 T-SQL 中有答案,我会尝试翻译它)并且我有以下内容:

  • 表 Department 以及部门名称和 ID 以及其他信息
  • 包含应用程序列表以及它们是否可部署(布尔值/位)的表格应用程序
  • 表 ApplicationMapping 链接 DepartmentId 和 ApplicationId(n:n 关系)

我试图了解每个部门有多少应用程序是可部署的(容易),但也有多少是不可部署的,以及完成的百分比。 (或至少类似于 (count(where deployable = true)/count(*))

我真的不知道如何进行这样的查询。 有什么想法吗?

【问题讨论】:

    标签: sql database ms-access count group-by


    【解决方案1】:

    (此答案是在 Access 2010 下开发和测试的。)

    首先,我们需要一个查询,为您提供按部门划分的申请总数。简单:

    SELECT DepartmentId, Count(*) AS CountOfApplications
    FROM ApplicationMapping
    GROUP BY DepartmentId
    

    说给我们

    DepartmentId  CountOfApplications
    ------------  -------------------
               1                    4
               2                    1
    

    您已经有了按部门计算可部署应用程序的查询,可能看起来像这样

    SELECT 
        am.DepartmentId, 
        Sum(IIf(a.Deployable,1,0)) AS CountOfDeployable
    FROM
        ApplicationMapping AS am
        INNER JOIN
        Applications AS a
            ON am.ApplicationId = a.ApplicationId
    GROUP BY DepartmentId
    

    假设它给了我们

    DepartmentId  CountOfDeployable
    ------------  -----------------
               1                  2
               2                  1
    

    那么我们需要做的就是将这两个查询连接在一起

    SELECT 
        q1.DepartmentId,
        q2.CountOfDeployable / q1.CountOfApplications AS pctDeployable
    FROM
        (
            SELECT DepartmentId, Count(*) AS CountOfApplications
            FROM ApplicationMapping
            GROUP BY DepartmentId
        ) AS q1
        INNER JOIN
        (
            SELECT 
                am.DepartmentId, 
                Sum(IIf(a.Deployable,1,0)) AS CountOfDeployable
            FROM
                ApplicationMapping AS am
                INNER JOIN
                Applications AS a
                    ON am.ApplicationId = a.ApplicationId
            GROUP BY DepartmentId
        ) AS q2
            ON q1.DepartmentId = q2.DepartmentId
    

    我们得到

    DepartmentId  pctDeployable
    ------------  -------------
               1            0.5
               2              1
    

    编辑:

    如果您想要一个包含所有部门的列表,即使是那些没有任何应用程序的部门,那么只需将整个前面的查询包装在另一个对 [Department] 表执行外部联接的查询中:

    SELECT
        d.DepartmentId,
        d.DepartmentName,
        IIf(IsNull(calc.DepartmentId),0,calc.CountOfApplications) AS totalApplications,
        calc.pctDeployable
    FROM
        Department AS d
        LEFT JOIN
        (
            SELECT 
                q1.DepartmentId,
                q1.CountOfApplications,
                q2.CountOfDeployable / q1.CountOfApplications AS pctDeployable
            FROM
                (
                    SELECT DepartmentId, Count(*) AS CountOfApplications
                    FROM ApplicationMapping
                    GROUP BY DepartmentId
                ) AS q1
                INNER JOIN
                (
                    SELECT 
                        am.DepartmentId, 
                        Sum(IIf(a.Deployable,1,0)) AS CountOfDeployable
                    FROM
                        ApplicationMapping AS am
                        INNER JOIN
                        Applications AS a
                            ON am.ApplicationId = a.ApplicationId
                    GROUP BY DepartmentId
                ) AS q2
                    ON q1.DepartmentId = q2.DepartmentId
        ) AS calc
            ON d.DepartmentId = calc.DepartmentId
    

    返回

    DepartmentId  DepartmentName  totalApplications  pctDeployable
    ------------  --------------  -----------------  -------------
               1  Department1                     4            0.5
               2  Department2                     1              0
               3  Department3                     0               
    

    【讨论】:

    • 谢谢,除了没有可部署应用程序且没有线路的部门外,它正在工作。我在部门表中添加了一个连接,以使用部门名称而不是部门 ID。
    • @user3031081 我已经调整了查询​​以包括没有可部署应用程序的部门。
    • (或者当这个部门没有申请时,应该是1)。也许我应该在部门列表中添加一个外部联接
    • @user3031081 是的,要包含没有应用程序根本的部门,您需要在 [Department] 表上进行外部联接。
    • 当我添加外连接时,它说 JOIN Expression not supported :/ 也许我需要做一个子查询。
    【解决方案2】:

    在这种情况下你必须使用 join -

    • 以下查询应该会给你想要的结果,但在 Oracle 数据库中。 我不知道如何翻译成 Access。

      SELECT department_id,
             total_cnt,
             (deployable_cnt / total_cnt) * 100 deployable_perc,
             100 - (deployable_cnt / total_cnt) * 100 not_deployable_perc
      FROM (SELECT dep.department_id,
                   COUNT(*) total_cnt,
                   SUM(CASE
                        WHEN app.deployable = 'Y' THEN
                        1
                        ELSE
                        0
                       END) deployable_cnt
             FROM department dep, applications app, applicationmapping appmap
            WHERE appmap.application_id = app.application_id
             and  appmap.department_id =  dep.department_id
       -- some other condition, if any
        GROUP BY dep.department_id)
      

    【讨论】:

    • 谢谢。我认为它应该适用于 T-SQL,但由于我们在 Access 中没有 CASE/WHEN,所以它不起作用:/但我保留它!
    猜你喜欢
    • 2018-04-05
    • 2019-02-12
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 2016-07-02
    • 2011-09-06
    • 1970-01-01
    相关资源
    最近更新 更多