【问题标题】:Closing percent MATH in MYSQL在 MYSQL 中关闭百分比数学
【发布时间】:2013-10-17 21:15:12
【问题描述】:

我想在查询中做数学运算,想知道用 PHP 还是 MYSQL 更好。 另外,如果我选择 MYSQL,任何人都可以帮助我进行查询。

目前为止

  SELECT COUNT(*) as total, booker, appdate,
  SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
  SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot
  FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker

我想从这个查询中获得更多统计信息。 我想做book / (book+tot) 但显然只有book!=0tot!=0,因为显然我不想将任何东西除以零。

有没有办法在 MYSQL 查询中做到这一点?

我希望我的输出是......

       book  | 14
       tot   | 25
       hold  | 35%

我还想按持有百分比从高到低排序。这可能吗????

【问题讨论】:

    标签: php mysql math average


    【解决方案1】:

    您可以使用子查询来实现您的要求,如下所示:

    SELECT *, IF(book + tot, 100*book/(book + tot), NULL) AS hold
    FROM (
      SELECT COUNT(*) as total, booker, appdate,
      SUM(status='DNS') book, SUM(status!='DNS') tot
      FROM appts WHERE WEEK(app_date)= WEEK(CURDATE()) GROUP BY booker
    ) AS subquery
    ORDER BY hold DESC
    

    请注意,我在几个地方使用了 MySQL 使用数字作为逻辑值的事实。所以不用CASE可以总结条件,不用<> 0校验也可以写IF的公式。

    【讨论】:

      【解决方案2】:

      朴素的方法:

      SELECT
          COUNT(*) as total,
          SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
          SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
      
          IF(  ( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
                 SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) ) = 0,
                0,
                SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) /
                 ( SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) +
                   SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) )
          ) AS hold
      FROM appts
      WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
      ORDER BY hold;
      

      或者为了不重复你的别名,使用子查询:

      SELECT *, IF (book + tot = 0, 0, book / (book + tot) * 100)
      FROM (
          SELECT
              COUNT(*) as total,
              SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
              SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
          FROM appts
          WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
      ) AS subq
      ORDER BY hold;
      

      或者,更聪明:) (book + tot = total)

      SELECT *, IF (total = 0, 0, book / total * 100)
      FROM (
          SELECT
              COUNT(*) as total,
              SUM(CASE WHEN status='DNS' THEN 1 ELSE 0 END) book,
              SUM(CASE WHEN status!='DNS' THEN 1 ELSE 0 END) tot,
          FROM appts
          WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
      ) AS subq
      ORDER BY hold;
      

      而且,只是为了好玩,最紧凑的形式:

      SELECT *, COALESCE(book / total * 100, 0) AS hold -- a division by 0 returns NULL
      FROM (
          SELECT
              COUNT(*) total,
              SUM(status='DNS') book, -- boolean "true" is internally integer "1"
              SUM(status!='DNS') tot,
          FROM appts
          WHERE WEEK(app_date) = WEEK(CURDATE()) GROUP BY booker
      ) AS subq
      ORDER BY hold;
      

      【讨论】:

      • @KyleK 顺便说一句,total 永远不会是 0,因为如果COUNT(*) = 0,那么根本就没有行:)
      猜你喜欢
      • 2021-01-21
      • 2013-03-14
      • 1970-01-01
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      相关资源
      最近更新 更多