如何在不事先知道数据的情况下从表中检索“异常”数据?

时间:2018-02-21 14:10:01

标签: sql-server

我有一张表一直在更新。 该表保留了一个列表,将商店与俱乐部联系起来,并管理每个商店+俱乐部的“折扣百分比”等。

表名:Policy_supplier

专栏:POLXSUP_DISCOUNT

假设表中的所有“供应商”都标有10%的折扣。 有人不小心签了一个供应商,占8%或15%(甚至是NULL) 如何生成查询以检索“异常”供应商?

2 个答案:

答案 0 :(得分:0)

您可以找到折扣模式,然后选择不等于该模式的记录:

WITH mode_discount AS (SELECT TOP 1 POLXSUP_DISCOUNT FROM table GROUP BY POLXSUP_DISCOUNT ORDER BY count(*) DESC)
SELECT * FROM table WHERE POLXSUP_DISCOUNT <> (SELECT POLSXUP_DISCOUNT FROM mode_discount);

答案 1 :(得分:0)

您可以将OVER子句与聚合一起使用来计算数据范围内的聚合并将其包含在结果中。例如,

SELECT avg(POLXSUP_DISCOUNT)
from Policy_supplier

时会返回单个平均值
SELECT POLXSUP_DISCOUNT, avg(POLXSUP_DISCOUNT) OVER()
from Policy_supplier

将返回每行的总体平均值。通常OVERPARTITION BY子句一起使用。如果您想要每个供应商的平均值,您可以写AVG() OVER(PARTITION BY supplierID)

要查找异常,您应该使用其中一个PERCENTILE函数,例如PERCENTILE_CONT。例如

select PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY POLXSUP_DISCOUNT) over()
from Policy_Supplier

将返回折扣值,低于该折扣值,您将找到95%的记录。其他5%以上的折扣可能是异常现象。

同样地,PERCENTILE_CONT(0.05)将返回一个折扣,低于该折扣,您将找到5%的记录

您可以将两者结合起来查找潜在例外记录,例如:

with percentiles as (
    select ID,
        POLXSUP_DISCOUNT, 
        PERCENTILE_CONT(0.95) WITHIN GROUP (ORDER BY POLXSUP_DISCOUNT) over() as pct95,
        PERCENTILE_CONT(0.05) WITHIN GROUP (ORDER BY POLXSUP_DISCOUNT) over() as pct05,
from Policy_Supplier)
select ID,POLXSUP_DISCOUNT
from percentiles
where POLXSUP_DISCOUNT>pct95 or POLXSUP_DISCOUNT<pct05