0

我正在尝试的东西有点复杂,我会尽力解释。

我完成了第一部分,即按小时对列求和。

例子

ID         TIMESTAMP          CUSTAFFECTED
1     10-01-2013 01:00:23       23
2     10-01-2013 03:00:23       55
3     10-01-2013 05:00:23       2369
4     10-01-2013 04:00:23       12
5     10-01-2013 01:00:23       1
6     10-01-2013 12:00:23       99
7     10-01-2013 01:00:23       22
8     10-01-2013 02:00:23       3

输出将是

      Hour          TotalCALLS   CUSTAFFECTED
  10/1/2013 01:00       3         46        
  10/1/2013 02:00       1         3
  10/1/2013 03:00       1         55
  10/1/2013 04:00       1         12
  10/1/2013 05:00       1         2369
  10/1/2013 12:00       1         99

询问

    SELECT   TRUNC(STARTDATETIME, 'HH24') AS hour, 
           COUNT(*) AS TotalCalls,
           sum(CUSTAFFECTED) AS CUSTAFFECTED
    FROM     some_table
    where STARTDATETIME >= To_Date('09-12-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') and
          STARTDATETIME <= To_Date('09-13-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') and
GROUP BY TRUNC(STARTDATETIME, 'HH')

我需要 什么我需要的总和 2 个查询并按时间戳/小时分组。第二个查询与第一个查询完全相同,只是 where 子句不同。

第二次查询

SELECT   TRUNC(RESTOREDDATETIME , 'HH24') AS hour, 
     COUNT(*) AS TotalCalls, 
     SUM(CUSTAFFECTED) AS CUSTRESTORED
FROM     some_table
where RESTOREDDATETIME >= To_Date('09-12-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') and
      RESTOREDDATETIME <= To_Date('09-13-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') 
GROUP BY TRUNC(RESTOREDDATETIME , 'HH24')

所以我需要减去 custaffected - custrestoed,并显示总计。

我添加了指向 excel 文件的链接。http://goo.gl/ioo9hg

谢谢

4

2 回答 2

0

我最近需要这样做,并且不得不使用它来让它工作。

挑战是让一个查询的结果链接到同一查询内的另一个查询,然后操作字段的返回值,以便从一个查询的结果集中给定字段中的值(称为 FieldA)减去不同结果集中的字段中的值,称为 FieldB。主题值是否是 COUNT(...) 等聚合函数的结果并不重要;它们可以是结果集中是否需要分组的任何数字字段。查看聚合函数中的值仅意味着您需要调整查询逻辑以将 GROUP BY 用于正确的字段。该方法需要在查询中创建内联视图,并将这些视图用作进行减法的数据源。

处理这种事情时的一个红鲱鱼是 MINUS 运算符(假设您使用的是 Oracle 数据库)但这不起作用,因为 MINUS 不是关于从结果集的字段值中减去另一个值,而是减去一组匹配从查询返回的最终结果集中的另一组记录中找到的记录。此外,MINUS 不是 SQL 标准运算符,因此如果您使用的不是 Oracle,您的数据库可能不支持它。尽管如此,当你需要它时,它仍然非常好。

好了,前奏就够了。这是您要使用的查询表单,例如我们希望按 YYYY-MM 分组的日期范围:

select inlineview1.year_mon, (inlineview1.CNT - inlineview2.CNT) as finalcnt from
 (SELECT TO_CHAR(*date_field*, 'YYYY-MM') AS year_mon, count(*any_field_name*) as CNT
  FROM *schemaname.tablename*
   WHERE *date_field* > TO_DATE('*{a year}-{a month}-{a day}*', 'YYYY-MM-DD') and
    *date_field* < TO_DATE('*{a year}-{a month}-{a day}*', 'YYYY-MM-DD') and 
    *another_field* = *{value_of_some_kind}* -- ... etc. ...
  GROUP BY TO_CHAR(*date_field*, 'YYYY-MM')) inlineview1,
 (SELECT TO_CHAR(*date_field*, 'YYYY-MM') AS year_mon, count(*any_field_name*) as CNT
  FROM *schemaname.tablename* 
   WHERE *date_field* > TO_DATE('*{a year}-{a month}-{a day}*', 'YYYY-MM-DD') and
     *date_field* < TO_DATE('*{a year}-{a month}-{a day}*', 'YYYY-MM-DD') and
     *another_field* = *{value_of_some_kind}* -- ... etc. ...
  GROUP BY TO_CHAR(*date_field*, 'YYYY-MM')) inlineview2
WHERE
inlineview1.year_mon = inlineview2.year_mon
order by *either or any of the final resultset's fields* -- optional

稍微抽象一点,一个书商希望查看 2013 年任何给定月份售出的净书籍数量的示例。为此,卖家必须从售出的数量中减去退回退款的书籍数量。他不在乎这本书什么时候被卖掉,因为他觉得退回的书在统计上代表着销售和收入的损失,无论它发生在什么时候和什么时候售出。例子:

select bookssold.year_mon, (bookssold.CNT - booksreturned.CNT) as netsalescount from
 (SELECT TO_CHAR(SALE_DATE, 'YYYY-MM') AS year_mon, count(TITLE) as CNT
  FROM RETAILOPS.ACTIVITY
   WHERE SALE_DATE > TO_DATE('2012-12-31', 'YYYY-MM-DD') and
    SALE_DATE < TO_DATE('2014-01-01', 'YYYY-MM-DD') and 
    OPERATION = 'sale'
  GROUP BY TO_CHAR(SALE_DATE, 'YYYY-MM')) bookssold,
 (SELECT TO_CHAR(SALE_DATE, 'YYYY-MM') AS year_mon, count(TITLE) as CNT
  FROM RETAILOPS.ACTIVITY
   WHERE SALE_DATE > TO_DATE('2012-12-31', 'YYYY-MM-DD') and
    SALE_DATE < TO_DATE('2014-01-01', 'YYYY-MM-DD') and 
    OPERATION = 'return'
  GROUP BY TO_CHAR(SALE_DATE, 'YYYY-MM')) booksreturned
WHERE
bookssold.year_mon = booksreturned.year_mon
order by bookssold.year_mon desc

请注意,为确保查询按预期返回,两个内联视图必须根据某些条件等值连接,如上所示,如下所示:

bookssold.year_mon = booksreturned.year_mon

或者计数记录的减法不能在 1:1 的基础上完成,因为查询解析器将不知道要从哪个记录中减去返回的带有分组计数值的记录。未能指定等值连接条件将产生笛卡尔连接结果,可能不是您想要的(尽管您可能会想要那个)。例如,在上面示例中的顶级 select 语句的返回字段列表中,在 'bookssold.year_mon' 之后添加 'booksreturned.year_mon' 并消除

bookssold.year_mon = booksreturned.year_mon

其 WHERE 子句中的条件将生成一个工作查询,该查询对结果集前两列中 YYYY-MM 值的 CNT 值进行减法计算,并将它们显示在第三列中。如果您需要,很容易知道这一点,因为它在业务趋势分析中具有可靠的应用,如果您不仅可以在给定的原子时间范围内比较销售和回报,而且可以在这些时间范围内以 1:N 的方式进行比较。

于 2014-03-28T16:58:34.963 回答
0

好的,现在正确的 sql 是有问题的文本,试试这个:

SELECT TRUNC(STARTDATETIME, 'HH24') AS hour,        
   COUNT(*) AS TotalCalls, 
   Sum(case when RESTOREDDATETIME is null Then 0 else 1 end) RestoredCount,
   Sum(CUSTAFFECTED) as CUSTAFFECTED,
   Sum(case when RESTOREDDATETIME is null Then 0 else CUSTAFFECTED end) CustRestored,
   SUM(CUSTAFFECTED) - 
    Sum(case when RESTOREDDATETIME is null Then 0 else CUSTAFFECTED end) AS CUSTNotRestored
FROM     some_table
where STARTDATETIME >= To_Date('09-12-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') 
   and STARTDATETIME <= To_Date('09-13-2013 00:00:00','MM-DD-YYYY HH24:MI:SS') 
GROUP BY TRUNC(STARTDATETIME, 'HH24')
于 2013-11-06T17:58:38.353 回答