联合所有请求的百分比

Percentage with union all request

正如我在这个问题中所问: 我在我的应用程序中记录了文件使用情况。有 3 个文件来源:

如果文件从 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 中的文件的比率。所以我设法做了这个请求:

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作为比率计算。

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

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

编辑:如何用您的查询替换我的示例中的 table 的示例是使用 subquery factoring,这是 Oracle 调用的 TSQL Common Table 表达式或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

我已将数据放在临时文件中 Table 以便于处理:

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

从顶部开始,您不需要 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);

因此,您可以创建一个派生的 table,而无需分组以获得所有宇宙。

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);

希望这个回答能帮到你 问候。

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

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

如果没有您的数据访问权限,则很难验证计算的正确性,但对于我的示例来说它是有效的。