2

我需要从表中计算 2 个日期之间的协议违规事件和持续时间,以实现类似于统计表的效果,如下图所示:

预期效果:

在此处输入图像描述

解释:

如您所见,我需要选择 Violations 表中存在的“Country”、“Site”以及:同一表“Violations”中数据库中存在的协议违规持续时间的“Numbers”、“Maximum”、“Minimum”和“Mean”两个日期之间。所以我们必须计算:

  • 按国家和站点在 Violations 表中存在的协议违规事件
  • 国家和站点违反协议的最小/最大/平均持续时间

在两种不同的条件下:

  • 从发现日期到报告日期发生的事件
  • 从报告日期到确认日期发生的事件

数据库结构:

可在 SQLFILDDLE:看这里

我将在附加的 SQLFIDDLE 中添加该代码,该代码具有更多表和一个查询,但对于此问题,它们现在是不必要的。随意使用它。我没有删除旧查询,因为有很好的方法:

  • '- 全部 -' 和
  • '- 未知 -' 值。-

违规表:

create table violations (
  id long,
  country varchar(20),
  site varchar(20),
  status_id int,
  trial_id int,
  discovered_date date,
  reporded_date date,
  confirmed_date date
);

场地表:

create table site (
  id long,
  site varchar(20)
);

我的第一次尝试:

这是我的新SQLFIDDLE,其中包含改进注释行所需的查询:

SELECT v.country as country, v.site as site,
  COUNT(*) as N --,
  --MAX(list of durations in days between discovered date to repored date on each violation by country and site) as "Maximum",
  --MIN(list of durations in days between discovered date to repored date on each violation by country and site) as "Minimum",
  --AVG(list of durations in days between discovered date to repored date on each violation by country and site) as "Mean"
FROM violations v
WHERE v.trial_id = 3
GROUP BY ROLLUP (v.country, v.site)

我已经设法用我的想法创建了抽象查询。但是我在为 MAX、MIN 和 AVG 编写正确查询时遇到问题,我们必须从国家和站点的每次违规之间discovered date的天数列表中选择最大/最小/平均值。reported date

请问你能帮帮我吗?

4

1 回答 1

0

Please check this query. It is simplified and may give you an idea and direction. If you need more then this then let me know. Copy and paste to see results. This query will select and calc only the results between two dates in where clause. You need to run inner query first w/out where to see all dates etc... This query counts violations between 2 dates. Not sure what is the list of duration in days... See below for count of duration. You may add MAX/MIN etc...

-- Days between (duration) = (end_date-start_date) = number of days (number) --
SELECT (to_date('14-MAR-2013') - to_date('01-MAR-2013')) days_between
  FROM dual
/


SELECT country, site
 , Count(*) total_viol
 , MAX(susp_viol) max_susp_viol
 , MIN(susp_viol) min_susp_viol
FROM
(
 SELECT 'GERMANY' country, '12222' site, 1 susp_viol, 2 conf_viol, trunc(Sysdate-30) disc_date, trunc(Sysdate-25) conf_date
   FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 3          , 14, trunc(Sysdate-20) , trunc(Sysdate-15)  FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 6          , 25, trunc(Sysdate-20) , trunc(Sysdate-15)  FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 2          , 1, trunc(Sysdate-20) , trunc(Sysdate-15)  FROM dual
  UNION
 SELECT 'GERMANY',  '13333'            , 10         , 5,  trunc(Sysdate-15) , trunc(Sysdate-10)  FROM dual
  UNION
 SELECT 'GERMANY',  '13333'            , 15         , 3,  trunc(Sysdate-15) , trunc(Sysdate-10)  FROM dual
  UNION
 SELECT 'GERMANY',  'Unknown Site'     , 0          , 7,  trunc(Sysdate-5) ,  trunc(Sysdate-2)  FROM dual
  UNION
 SELECT 'RUSSIA',  '12345'             , 1          , 5,  trunc(Sysdate-20) ,  trunc(Sysdate-15)  FROM dual
  UNION
 SELECT 'RUSSIA',  '12345'             , 2          , 10,  trunc(Sysdate-15) ,  trunc(Sysdate-12)  FROM dual
 UNION
SELECT 'RUSSIA',  'Unknown Site'      , 10          , 10,  trunc(Sysdate-3) ,  trunc(Sysdate-1)  FROM dual
 ) 
  -- replace sysdate with your_date-default format is to_date('14-MAR-2013') or give format mask
 WHERE conf_date BETWEEN trunc(Sysdate-20) AND trunc(Sysdate-10)
 GROUP BY ROLLUP (country, site)
 ORDER BY country, site
/

Count of duration:

SELECT country, site, (conf_date-disc_date) duration, count(*) total_durations 
  FROM
 (
 SELECT 'GERMANY' country, '12222' site, 1 susp_viol, 2 conf_viol, trunc(Sysdate-30) disc_date, trunc(Sysdate-20) conf_date
   FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 3          , 14, trunc(Sysdate-20) , trunc(Sysdate-12)  FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 6          , 25, trunc(Sysdate-20) , trunc(Sysdate-12)  FROM dual
  UNION
 SELECT 'GERMANY',  '12222'            , 2          , 1, trunc(Sysdate-20) , trunc(Sysdate-12)  FROM dual
  UNION
 SELECT 'GERMANY',  '13333'            , 10         , 5,  trunc(Sysdate-12) , trunc(Sysdate-6)  FROM dual
  UNION
 SELECT 'GERMANY',  '13333'            , 15         , 3,  trunc(Sysdate-17) , trunc(Sysdate-11)  FROM dual
  UNION
 SELECT 'GERMANY',  'Unknown Site'     , 0          , 7,  trunc(Sysdate-5) ,  trunc(Sysdate-2)  FROM dual
  UNION
 SELECT 'RUSSIA',  '12345'             , 1          , 5,  trunc(Sysdate-20) ,  trunc(Sysdate-15)  FROM dual
  UNION
 SELECT 'RUSSIA',  '12345'             , 2          , 10,  trunc(Sysdate-15) ,  trunc(Sysdate-12)  FROM dual
  UNION
 SELECT 'RUSSIA',  'Unknown Site'      , 10          , 10,  trunc(Sysdate-3) ,  trunc(Sysdate-1)  FROM dual
 ) 
 WHERE conf_date BETWEEN trunc(Sysdate-20) AND trunc(Sysdate-10) 
  GROUP BY ROLLUP (country, site, (conf_date-disc_date))
  ORDER BY country, site
 /
于 2013-03-14T12:50:51.917 回答