【问题标题】:Counting partial values or conditional values计算部分值或条件值
【发布时间】:2012-08-10 14:40:10
【问题描述】:

我希望有人可以在这里提供帮助和一些建议。我正在尝试获得一个相当复杂的结果,但不确定是否可以将其作为一个带有子查询、联合的查询,或者只是单独的查询在事后合并到 excel 中。

我正在使用来自我的前任的旧数据库,其中包含以下表格: 业务(使用的列:id、sector、state) 表单(使用的列:已提交 (Y/N)、id、business_id) 库存(使用的列:In_stock (Y/N)、id、form_id)

我正在尝试获得如下所示的最终结果:

| SubmittedForms | Unsubmitted Forms | Sector | State |
|-----------------------------------------------------|
|       10       |         5         |  Agr   |  UT   |
|       0        |         7         |  Chem  |  MT   |
|       2        |         1         |  Bio   |  OK   |
|       13       |         0         |  Chem  |  NM   |

我遇到的主要问题是,虽然提交的表单不需要任何进一步的参数并且是一个简单的计数,但未提交的表单取决于 Inventory.in_stock='Y'。这是我对提交表单的查询:

SELECT COUNT(Forms.id) AS Submitted, Business.sector, Business.state
FROM Forms
JOIN Business ON Forms.business_id=Business.id
WHERE Forms.submitted='Y'
GROUP BY Business.state, Business.sector

很遗憾,我似乎无法正确计算未提交的表单编号。它只返回该部门的 in_stock 为 Y 的总行数。

如果对 Submitted 和 Unsubmitted 运行单独的查询更容易,这对最终结果来说很好,但我需要一些帮助才能获得正确计数的未提交表单,其中 in_stock 标记为 Y。此外,我尝试使用 COUNT DISTINCT 但是耗时太长,10分钟后仍在运行。我可以在单个查询选项中设想的另一个复杂情况是提交或未提交的表单中可能出现 0/null 值

非常感谢任何帮助!

【问题讨论】:

    标签: mysql count subquery distinct


    【解决方案1】:

    一个选项:

    SELECT COUNT(CASE WHEN Forms.submitted = 'Y' THEN 1 END) SubmittedForms,
           COUNT
            ( CASE WHEN Forms.submitted = 'N'
                    AND EXISTS ( SELECT 1
                                   FROM Inventory
                                  WHERE form_id = Forms.id
                                    AND in_stock = 'Y'
                               )
                   THEN 1
               END
            ) UnsubmittedForms,
           Business.sector Sector,
           Business.state State
      FROM Forms
     RIGHT
     OUTER
      JOIN Business 
        ON Forms.business_id = Business.id
     GROUP
        BY Business.sector,
           Business.state
    ;
    

    另一种选择,效果可能更好:

    SELECT COUNT(CASE WHEN Forms.submitted = 'Y' THEN 1 END) SubmittedForms,
           COUNT(CASE WHEN Forms.submitted = 'N' THEN 1 END) UnsubmittedForms,
           Business.sector Sector,
           Business.state State
      FROM ( SELECT *
               FROM Forms
              WHERE submitted = 'Y'
                 OR id IN ( SELECT DISTINCT form_id
                              FROM Inventory
                               AND in_stock = 'Y'
                          )
           ) Forms
     RIGHT
     OUTER
      JOIN Business 
        ON Forms.business_id = Business.id
     GROUP
        BY Business.sector,
           Business.state
    ;
    

    【讨论】:

    • 谢谢,这向我展示了如何在一个结果中获取已提交/未提交的列,但未考虑未提交文档的 In_stock 变量。
    • @KevinO.:啊,对不起。所以,我很困惑。您写道“未提交的表单依赖于 Inventory.in_stock='Y'”,但您没有解释依赖关系。看起来InventoryForms 的孩子,而不是相反;那么,您是否正在寻找具有至少一个 Inventory 记录和in_stock = 'Y' 的未提交表单的计数?或者您是否正在寻找具有in_stock = 'Y' 且属于未提交表单的Inventory 记录计数?或者 。 . . ?
    • 我的道歉,回想起来你是对的,但不清楚。是的,我的前任基本上在层次结构中下降:业务、表单、库存,所以库存是表单的子级。我正在寻找至少有一个 Inventory 记录与 in_stock = 'Y' 的未提交表单的计数
    • 感谢您的帮助,第一个选择效果很好,我相信第二个也可以。我在没有太多背景知识的情况下投入到 SQL 工作中,所以我仍然在学习大部分功能,以前不知道 COUNT CASE,现在我知道了,谢谢!
    • @KevinO.:不客气!澄清一下,没有明显的COUNT(CASE ...) 功能。它的工作方式是,COUNT(...) 计算所有非空值(例如,COUNT(1)COUNT(0) 等价于 COUNT(*),而 COUNT(NULL) 始终计算为零),以及 @987654337如果不满足任何条件,@表达式的计算结果为 NULL。 (这可以通过使用ELSE 子句——CASE WHEN ... THEN 1 ELSE NULL END 更明确——但是当CASE 表达式包含在COUNT 中时,我通常不会打扰。)
    猜你喜欢
    • 1970-01-01
    • 2015-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-07
    • 2021-06-21
    • 2019-11-22
    • 2011-06-28
    相关资源
    最近更新 更多