我有一个反映缓存命中率的表格,形式如下:
Action | logic name | count
PUSH a 123
HIT a 57
PUSH b 321
HIT b 77
PUSH c 111
HIT c 50
a 的命中率为 57/123,b 的命中率为 77/321。
操作列有 2 个值: PUSH:指令被推送到缓存,未被使用 HIT:指令被推送到缓存并被使用
逻辑名称是指决定推送哪条指令的算法名称。计数是推送或命中了多少指令。
我正在努力找到一种方法来添加另一列来指示每种算法的命中率。 怎么能做到呢?
为了清楚起见,我希望看到这样的东西:
Action | logic name | count | hit rate %
PUSH a 123 46.3
HIT a 57 46.3
PUSH b 321 23.9
HIT b 77 23.9
PUSH c 111 45.0
HIT c 50 45.0
如果每个逻辑名称的每个操作正好有 1 行,则可以编写如下内部查询:
SELECT a.action, a.logic_name, a.count,
((SELECT count FROM table WHERE logic_name = a.logic_name AND action = 'HIT')/
(SELECT count FROM table WHERE logic_name = a.logic_name AND action = 'PUSH'))*100
AS hit_rate
FROM table a;
如果每个逻辑名称的每个操作正好有 1 行,并且 Action 只有HIT
和PUSH
,那么您可以使用带有条件的min()
(或max()
(窗口分析函数,如下所示:
select the_table.*,
min(case when Action = 'HIT' then count end) over(partition by logic_name) /
min(case when Action = 'PUSH' then count end) over(partition by logic_name) * 100 as hit_rate
from the_table
我会用PIVOT
解决这个问题。此解决方案更加灵活,因为即使您每logic_name
有超过 2HIT-PUSH
行,它也可以工作。这个想法是将HIT
和RATE
表示为每个logic_name
的列:
DECLARE @t1 TABLE ([action] VARCHAR(50), logic_name VARCHAR(50), [count] INT)
INSERT into @t1 ([action], logic_name, [count]) VALUES
('PUSH','a',123)
,('HIT','a',57)
,('PUSH','b',321)
,('HIT','b',77) ;
WITH cte AS
(
SELECT [logic_name]
,[PUSH]
,[HIT]
,(CAST ([HIT] AS DECIMAL)/[PUSH]) AS HitRate
FROM (
SELECT [action]
,[logic_name]
,[count]
FROM @t1
) AS Source
PIVOT
(
SUM([count])
FOR [action] IN ([PUSH],[HIT])
) AS PivotTable
)
SELECT tt.*,c.HitRate
FROM @t1 tt
JOIN cte c ON c.logic_name = tt.logic_name