SQL-如何按类似日期检索

时间:2017-12-04 18:58:59

标签: sql oracle group-by count oracle12c

好的,我有一个包含user_id列和submitted_dtm列的表。

我想找到用户在1天内提交多条记录的实例,并计算发生了多少次。

我尝试过像

这样的事情
select * from table_t t where 
(select count(*) from table_t t2 where 
t.user_id = t2.user_id and
t.pk!=t2.pk and
t.submitted_dtm between t2.submitted_dtm-.5 and t2.submitted_dtm+.5)>0; 

问题是此查询返回日期组中每条记录的结果。相反,我只想要每个日期组的结果。理想情况下,我只是得到该组的计数。

也就是说,如果我有6条记录:

user_id     submitted_dtm
--------------------------
1            12/04/2017 1:15
1            12/04/2017 5:50
2            11/25/2017 2:00
2            11/25/2017 3:25
2            11/25/2017 6:05
2            10/06/2017 4:00

我想要2个结果,2个计数和3个计数。

是否可以在sql中执行此操作?

4 个答案:

答案 0 :(得分:3)

跟进Dessma的回答。

select user_id, trunc(submitted_dtm), count(1)
  from table_t
 group by user_id, trunc(submitted_dtm)
having count(1) > 1;

Sqlfiddle

答案 1 :(得分:3)

在Oracle 12.1及更高版本中,您可以使用match_recognize子句轻松解决此类问题。链接到下面的文档(带示例);我对下面解决方案的唯一注意事项是我将日期保留在DATE数据类型中,如果输出用于进一步的计算,这一点尤为重要。如果不是,您可以使用适合您的用户的任何格式模型在TO_CHAR()内包装。

https://docs.oracle.com/database/121/DWHSG/pattern.htm#DWHSG8956

with
  inputs ( user_id, submitted_dtm ) as (
    select 1, to_date('12/04/2017 1:15', 'mm/dd/yyyy hh24:mi') from dual union all
    select 1, to_date('12/04/2017 5:50', 'mm/dd/yyyy hh24:mi') from dual union all
    select 2, to_date('11/25/2017 2:00', 'mm/dd/yyyy hh24:mi') from dual union all
    select 2, to_date('11/25/2017 3:25', 'mm/dd/yyyy hh24:mi') from dual union all
    select 2, to_date('11/25/2017 6:05', 'mm/dd/yyyy hh24:mi') from dual union all
    select 2, to_date('10/06/2017 4:00', 'mm/dd/yyyy hh24:mi') from dual
  )
-- End of simulated inputs (for testing only, not part of the solution).
-- SQL query begins below this line. Use your actual table and column names.
select user_id, submitted_dtm, cnt
from   inputs
match_recognize(
  partition by user_id
  order by     submitted_dtm
  measures     trunc(a.submitted_dtm) as submitted_dtm,
               count(*) as cnt
  pattern      ( a b+ )
  define       b as trunc(submitted_dtm) = trunc(a.submitted_dtm)
);

   USER_ID SUBMITTED_DTM              CNT
---------- ------------------- ----------
         1 2017-12-04 00:00:00          2
         2 2017-11-25 00:00:00          3

答案 2 :(得分:2)

我没有数据来测试它,但我怀疑这样的事情可以解决问题:

SELECT user_id,To_char(t.submitted_dtm, 'dd/mm/yyyy'), COUNT(*)
  FROM table_t t
 INNER JOIN table_t t2
    ON t.user_id = t2.user_id
   AND t.pk != t2.pk
   AND t.submitted_dtm BETWEEN t2.submitted_dtm - .5 AND
       t2.submitted_dtm + .5
 GROUP BY user_id,To_char(t.submitted_dtm, 'dd/mm/yyyy')
HAVING COUNT(*) > 1

答案 3 :(得分:1)

这是如何获取实例的一般概念。

mysql> select suppliers.valid AS 'Supplier Status' from suppliers;
+-----------------+
| Supplier Status |
+-----------------+
|               0 |
|               0 |
|               0 |
|               0 |
|               0 |
|               0 |
|               1 |
|               1 |
|               1 |
|               1 |
|               1 |
|               1 |
|               1 |
|               1 |
|               1 |
+-----------------+

可以根据select user_id, t1.submitted_dtm t1submitted, t2.submitted_dtm t2submtted from table_t t1 join table_t t2 using (user_id) where t2.submitted_dtm > t1.submitted_dtm and t2.submitted_dtm - t1.submitted_dtm <= 1; 的含义以某种方式修改最后一行。

要计算实例,请从上面创建派生表,然后从中选择count(*)。