联合所有请求的百分比

时间:2015-06-10 12:37:27

标签: sql oracle union-all

正如我在这个问题中提到的那样:Oracle SQL Group By if我在我的应用程序中记录文件使用情况。有3个文件来源:

  • MDA
  • 其他

如果文件是从MDA打开两次而从Pool打开一次,我会得到两个条目:

TESTID        SITE       LATEST_READ READ_COUNT FILE_ORIGIN_ID
------------- ---------- ----------- ---------- --------------
File1        |Site1     |02/05/13   |         2|             1 
File1        |Site2     |22/01/14   |         3|             2 

我想要实现的是获取不在池中的文件或按站点分组的MDA的比率。所以我设法做了这个resquest:

SELECT Count(TESTID) as OTHER_FILES, SITE, 'OTHERS'
FROM USER_STATS.FILE_USAGE_LOG
WHERE TESTID not in (
  -- Files that are on Pool OR MDA
  SELECT TESTID
  FROM USER_STATS.FILE_USAGE_LOG
  WHERE FILE_ORIGIN_ID < 2
)
AND LATEST_READ between '01/05/2015' and '01/06/2015'
GROUP BY Site

UNION ALL
SELECT Count(TESTID) as OTHER_FILES, site, 'Files that are at least in Pool or MDA'
FROM USER_STATS.FILE_USAGE_LOG
WHERE TESTID in (
  -- Files that are on Pool OR MDA
  SELECT TESTID
  FROM USER_STATS.FILE_USAGE_LOG
  WHERE FILE_ORIGIN_ID < 2
)
AND LATEST_READ between '01/05/2015' and '01/06/2015'
GROUP BY Site

这给了我这个:

18      BR-CTA      Files that are at least in Pool or MDA
324     BR-CTA      OTHERS
26      BR-CTA-VPN  OTHERS
5       CN-TSN-VPN  OTHERS
2040    FR-LYON     Files that are at least in Pool or MDA
248     FR-LYON     OTHERS
1       IN-BLR      Files that are at least in Pool or MDA
1       IN-PUNE     OTHERS
810     JP-SAIT     OTHERS
48      JP-SAIT     Files that are at least in Pool or MDA
...

我想有这个:

94%         BR-CTA      Ratio -- 94% in OTHER
100%        BR-CTA-VPN  Ratio -- 100% in OTHER
100%        CN-TSN-VPN  Ratio -- 100% in OTHER
10%         FR-LYON     Ratio -- 10% in OTHER
0%          IN-BLR      Ratio -- 0% in OTHER
100%        IN-PUNE     Ratio -- 100% in OTHER
94%         JP-SAIT     Ratio -- 94% in OTHER
...

但无论我怎样尝试,我都无法实现这一点。 我该怎么做?

我使用nbTotal / (nbOther) * 100作为比率计算。

4 个答案:

答案 0 :(得分:2)

有几种方法可以做到这一点,可能或最好的方法部分取决于您的RDBMS。但是,这是一种方式。为简单起见,我将上面的查询替换为IntermediateResults表。实际上,您可以将查询与CTE,派生表,临时表或表变量一起使用。

CREATE TABLE IntermediateResults (OtherFiles INT, Site VARCHAR(20), Message VARCHAR(100));
GO
INSERT INTO IntermediateResults (OtherFiles,Site,Message) VALUES (18,'BR-CTA','Files that are at least in Pool or MDA');
INSERT INTO IntermediateResults (OtherFiles,Site,Message) VALUES (324,'BR-CTA' ,'OTHERS');
INSERT INTO IntermediateResults (OtherFiles,Site,Message) VALUES (26,'BR-CTA-VPN','OTHERS');
INSERT INTO IntermediateResults (OtherFiles,Site,Message) VALUES (1,'IN-BLR','Files that are at least in Pool or MDA');
GO


SELECT COALESCE(o.Site,p.Site) Site
      ,Ratio = CASE WHEN o.OtherFiles IS NULL THEN 0
                    WHEN p.OtherFiles IS NULL THEN 100
                    ELSE 100 * o.OtherFiles/(p.OtherFiles + o.OtherFiles) END
FROM
  (SELECT * FROM IntermediateResults WHERE Message = 'OTHERS') o
FULL JOIN
  (SELECT * FROM IntermediateResults WHERE Message <> 'OTHERS') p
ON o.Site = p.Site

结果:

BR-CTA      94
IN-BLR      0
BR-CTA-VPN  100

编辑:如何用我的查询替换我的示例中的表的一个示例是使用subquery factoring,这就是Oracle调用TSQL公用表表达式或WITH构造。

WITH IntermediateResults AS (
    /*your query here*/
)
SELECT COALESCE(o.Site,p.Site) Site
      ,Ratio = CASE WHEN o.OtherFiles IS NULL THEN 0
                    WHEN p.OtherFiles IS NULL THEN 100
                    ELSE 100 * o.OtherFiles/(p.OtherFiles + o.OtherFiles) END
FROM
  (SELECT * FROM IntermediateResults WHERE Message = 'OTHERS') o
FULL JOIN
  (SELECT * FROM IntermediateResults WHERE Message <> 'OTHERS') p
ON o.Site = p.Site

答案 1 :(得分:1)

从顶部开始,您不需要UNION ALL查询,您可以使用此查询检索数据。

我省略了便于阅读的范围期限。

SELECT COUNT(TESTID) AS OTHER_FILES,SITE
,CASE WHEN FILE_ORIGIN_ID < 2 THEN 'Files that are at least in Pool or MDA' ELSE 'OTHERS' END AS validCondition
FROM FILE_USAGE_LOG as pivot
GROUP BY pivot.TESTID
,(CASE WHEN FILE_ORIGIN_ID < 2 THEN 'Files that are at least in Pool or MDA' ELSE 'OTHERS' END);

因此,你可以创建一个派生表,不用分组来获得所有的宇宙。

SELECT COUNT(TESTID) AS OTHER_FILES,SITE
,CASE WHEN FILE_ORIGIN_ID < 2 THEN 'Files that are at least in Pool or MDA' ELSE 'OTHERS' END AS validCondition,
(COUNT(TESTID)/MAX(total))*100 AS ratio
FROM FILE_USAGE_LOG as pivot
CROSS JOIN(SELECT COUNT(TESTID) AS total FROM FILE_USAGE_LOG) AS u
GROUP BY pivot.TESTID
,(CASE WHEN FILE_ORIGIN_ID < 2 THEN 'Files that are at least in Pool or MDA' ELSE 'OTHERS' END);

我希望这个答案可以帮到你 问候。

答案 2 :(得分:0)

我已将数据放入临时表中以便于处理:

DECLARE @tmp  TABLE (readcount INT, site VARCHAR(40), origin VARCHAR(40))

INSERT INTO @TMP (readcount, site, origin) VALUES (18,'BR-CTA','Files that are at least in Pool or MDA')
INSERT INTO @TMP (readcount, site, origin) VALUES (324,'BR-CTA','OTHERS')
INSERT INTO @TMP (readcount, site, origin) VALUES (26,'BR-CTA-VPN','OTHERS')
INSERT INTO @TMP (readcount, site, origin) VALUES (5,'CN-TSN-VPN','OTHERS')

我认为你想要的是:

SELECT 
  percentage = 
   ((SELECT readcount      FROM @tmp T2 WHERE T2.site = T.site AND origin = 'OTHERS') * 100.0 / 
    (SELECT SUM(readcount) FROM @tmp T3 WHERE t3.site = T.site GROUP BY SITE) ),
  site
FROM @tmp t
GROUP BY site

这导致

94.736842105263 BR-CTA
100.000000000000    BR-CTA-VPN
100.000000000000    CN-TSN-VPN

答案 3 :(得分:0)

我认为此查询可能对此有所帮助:

with t as (
    select site,
        count(case when dsc = 'MDA' then testid end) mda,
        count(case when dsc = 'OTH' then testid end) oth
      from (
        select testid, site,
          case when exists (
              select testid from file_usage_log 
                 where file_origin_id<2 and testid = ful.testid) 
            then 'MDA' else 'OTH' end dsc
        from file_usage_log ful
        where latest_read between date '2015-05-01' and date '2015-06-01')
      group by site)
  select site, round(100*oth/(oth+mda)) percent from t

SQLFiddle

如果没有您的数据访问权限,很难验证计算的核心性,但对于我的示例,它可以正常工作。