【问题标题】:PostgreSQL calculate threshold queryPostgreSQL计算阈值查询
【发布时间】:2016-08-10 12:13:05
【问题描述】:

我有一个带有表 t1 的 postgresql db,我想计算一个阈值。 例如,阈值应该是汽车 1 使用的燃料比所有汽车的 75% 多,汽车 2 使用的燃料比所有汽车的 50% 多,...。 数学上我明白我想做什么,但我不知道如何构建查询

id | name | value | threshold
________________________

1  | car1 |  30   |  ...%
2  | car2 |  15   |  ..%
3  | car3 |   7   |
4  | car4 |   5   |

这是一个 sql fiddle http://sqlfiddle.com/#!15/1e914/1

UPDATE t1
SET threshold = 
    select count(value)
     from t1

where (value > [over each row]) 然后是*100/总计数()

很抱歉这次糟糕的尝试,但我有点迷路了。还尝试了一些聚合函数。

【问题讨论】:

  • 看看100 * PERCENT_RANK() OVER (ORDER BY value)100 * CUME_DIST() OVER (ORDER BY value)
  • @dnoeth 这两个都不起作用,因为解决方案是相对于最省油的汽车而言的,而不是针对整个人口计算的。
  • @Patrick:如果这些功能不起作用,那么您的答案也不正确。两者都只是您的RANK/COUNT 的细微变化:-)
  • @dnoeth 不正确。我正在使用(rank() - 1) / count(),它给出了这个问题的准确结果。 - 1 可能很轻微,但这就是你不能使用内置函数的原因。
  • @Patrick:好的,根据预期结果,两者都不正确,但这只是基于四行的描述 :-) 这就是为什么我写他应该看看这些功能是否符合他的需要。 PERCENT_RANK 基于(RANK-1)/(COUNT-1),即小于当前值的行数,CUME_DIST基于小于或等于

标签: sql postgresql math window-functions threshold


【解决方案1】:

您可以使用window function 非常优雅地解决这个问题:

UPDATE t1
SET threshold = sub.thr
FROM (
  SELECT id, 100. * (rank() OVER (ORDER BY value) - 1) / count(*) OVER () AS thr
  FROM t1) sub
WHERE t1.id = sub.id;

rank() 函数给出有序集合中的排名(从 1 开始),在本例中是列value,然后除以集合中的总行数。请注意,count(*) OVER () 会计算 分区 中的总行数,但它不会像常规的 count(*) 那样聚合行。

【讨论】:

  • 谢谢大家的帮助。在上面的 sqlfiddle 链接中,您可以看到 rank()、percent_rank()、cume_dist() 之间的差异。我想我在找percent_rank。我改变了订单,现在我可以说 33% 的汽车比 car2 使用更多的燃料。 (顺便说一句,我真正的桌子不是关于汽车的)。要添加的一件事,窗口功能不适用于 UPDATE
  • 您可以将窗口函数包装在子选择中,然后它应该可以工作。请参阅更新的答案。请注意,使用percent_rank() 给出的结果与您在问题中陈述的结果不同。该百分比相对于最省油的汽车,而该函数针对所有行进行计算。 (rank() - 1) / count(*) 给出了你想要的结果。
  • true,(rank() ... 是正确的函数,适用于我的问题。再次感谢。
【解决方案2】:
WITH    q AS
        (
        SELECT  *,
                (RANK() OVER (ORDER BY value) - 1) * 100. / COUNT(*) OVER () nt
        FROM mytable
        )
UPDATE  mytable
SET     threshold = nt
FROM    q
WHERE   mytable.id = q.id

【讨论】:

    【解决方案3】:

    您要计算使用燃料的百分比吗?

    UPDATE t1 
    SET threshold = 
        (select value * 100 / t2.sumValue
        from (select sum(value) sumValue from t1) t2
        )
    

    或者如果你想计算具体的阈值,可以显示你的预期结果吗?

    【讨论】:

      猜你喜欢
      • 2021-11-01
      • 2020-07-05
      • 2011-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 1970-01-01
      • 2021-03-23
      相关资源
      最近更新 更多