我有一个具有以下结构和数据的表:
create table PTEST
(
col_name VARCHAR(50),
col_value VARCHAR(50)
)
COL_NAME COL_VALUE
-----------------------
first apple
first banana
second apple
second banana
second orange
third apple
third banana
**) 我要做的是将col_value
列中的每个值分为两类:[常见,不常见]
**)'Common'
如果一个值出现在每个中,则考虑一个值col_name
,因此apple
很常见,因为它出现在 中col_name = first and col_name = second and col_name = third
。对于banana
. Orange
并不常见,因为它只是出现在col_name = second
.
所需的输出将是这样的:
COL_NAME COL_VALUE STATUS
---------------------------------
first apple Common
first banana Common
second banana Common
second apple Common
second orange Not common
third apple Common
third banana Common
我为此写的查询是:
select col_name,
col_value,
case
when count_col = count_val then
'Common'
else
'Not common'
end STATUS
from (select t.col_name,
count(distinct t.col_name) over() count_col,
t.col_value,
count(t.col_value) over(partition by t.col_value) count_val
from PTEST t)
我想知道是否有更好的方法来做到这一点。
提前致谢
执行此操作的两种方法如下(下面的所有代码都可以在SQL Server 的小提琴中找到- 有计划 -在这里- 最后的性能分析:
桌子:
填充它:
第一种方式:
首先,我们想知道一个水果在整个表格中出现了多少次。
结果:
您有多种方法可以找到水果出现的次数少于您定义的 cnt (3) 的最大值
common
- 所以我们一眼就能看出orange
是uncommon
。所以,我正在使用 CTE 来做到这一点:
结果:
瞧!
为了更接近您自己的原始(不工作 - 见小提琴)查询,您可以这样做(再次,在小提琴中):
结果相同。
第二种方式:
如果您正在运行没有窗口功能的古董(或最新版本的 MySQL :-)),您也可以这样做:
结果:
等等,再来一次!
你在问题中问:
因此,我在小提琴的底部添加了以下几行(在此处记录):
最后
从 db<>fiddle 获得非常细粒度的时序似乎是不可能的,但计划很有趣。
窗口函数查询产生以下计划(23 行):
而“老式”的则产生了这个 11 行的计划:
鉴于我们缺乏明确的时间安排 - 无论如何,用如此少量的数据进行测试或多或少毫无意义,我会敦促您针对您自己的表和硬件测试任何和所有建议的解决方案......但是,作为一项规则拇指,计划越长,它们越慢,并且窗口函数会产生开销!从这里:
将来,在问这种性质的问题时,请您自己提供小提琴-它提供了单一的事实来源并消除了重复劳动-帮助我们为您提供帮助!:-)