【问题标题】:Selecting totals as three fields from same table as one query?从同一个表中选择总计作为三个字段作为一个查询?
【发布时间】:2013-06-27 10:15:59
【问题描述】:

我有一张桌子,里面有各种订单:

ID | Date       | etc...
1  | 2013-01-01 | etc
2  | 2013-02-01 | etc
3  | 2013-03-01 | etc
4  | 2013-04-01 | etc
5  | 2013-05-01 | etc
6  | 2013-06-01 | etc
7  | 2013-06-01 | etc
8  | 2013-03-01 | etc
9  | 2013-04-01 | etc
10 | 2013-05-01 | etc

我想要一个以结果结尾的查询:

overallTotal | totalThisMonth | totalLastMonth
10           | 2              | 1

但我想在一个查询中做到这一点!我正在尝试找到一种使用子查询来执行此操作的方法。到目前为止,我有:

SELECT * from (
  SELECT count(*) as overallTotal from ORDERS
)

如何将它与其他子查询结合起来,以便在一个查询中获得总数?

更新

最初的问题是针对 MySQL 的,但我现在需要针对 Firebird。

【问题讨论】:

  • SELECT * 需要什么?
  • 你真的需要columns而不是rows的结果吗?
  • 我想行也可以工作?

标签: mysql sql firebird firebird2.5


【解决方案1】:

使用条件和可以做到(MySQL 语法):

select 
    count(*) as overallTotal, 
    sum(if(Month(Date)+12*Year(Date)=Month(GetDate())+12*Year(GetDate()), 1, 0)) 
       as totalThisMonth 
    sum(if(Month(Date)+12*Year(Date)=Month(GetDate())+12*Year(GetDate())-1, 1, 0)) 
       as totalThisMonth;
from mytable

使用month+12*year 公式来避免年份变化的问题。

更新

Firebird 同样适用,您只需将Month(x) 替换为EXTRACT (MONTH FROM x),将Year(x) 替换为EXTRACT (YEAR FROM x),将Getdate() 替换为CURRENT_TIME。这看起来很难看,所以我不会放在这里,但是您可以轻松地自己做。

【讨论】:

    【解决方案2】:

    可能使用 IF 语句结果的 SUM,IF 检查它是否是相关日期。

    SELECT COUNT(*), 
        SUM(IF(YEAR(Date) = YEAR(CURDATE()) AND MONTH(Date) = MONTH(CURDATE()), 1, 0))
        SUM(IF((YEAR(Date) = YEAR(CURDATE()) AND MONTH(Date) = MONTH(CURDATE()) - 1) OR (YEAR(Date) = YEAR(CURDATE()) - 1 AND MONTH(Date) = 12 AND MONTH(CURDATE()) = 1), 1, 0))
    from ORDERS
    

    复杂性是由于在查找上个月时应对年份的变化而引起的

    【讨论】:

      【解决方案3】:

      我看到你已经在使用子查询,所以为什么不做如下的事情,

      SELECT
      (SELECT count(*) from ORDERS) as overallTotal,
      (SELECT count(*) from ORDERS where Date between ... and ...) as totalThisMonth,
      (SELECT count(*) from ORDERS where Date between ... and ...) as overallTotal
      

      【讨论】:

        【解决方案4】:
        SELECT
          (SELECT COUNT(*) FROM C AS total) AS T,
          (SELECT COUNT(*) AS thisMonth FROM C WHERE MONTH(d) = 6) AS A,
          (SELECT COUNT(*) AS lastMonth FROM C WHERE MONTH(d) = 5) AS B;
        

        请注意“月份”是“硬编码”的——但在应用程序级别提取“当前月份”应该不会太难。如果你真的需要,你可以在 SQL 级别使用 类似 的东西来做:

        SELECT
          (SELECT COUNT(*) FROM C AS total) AS T,
          (SELECT COUNT(*) AS thisMonth FROM C WHERE MONTH(d) = MONTH(NOW()) ) AS A,
          (SELECT COUNT(*) AS lastMonth FROM C WHERE MONTH(d) = (MONTH(NOW())+11)%12) ) AS B;
        

        【讨论】:

          猜你喜欢
          • 2014-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-02-07
          • 2011-07-09
          相关资源
          最近更新 更多