【问题标题】:Division in SQL Query StatementSQL查询语句中的除法
【发布时间】:2011-01-13 16:40:41
【问题描述】:

我有两个查询返回单列双精度值:

(SELECT scale 
   FROM (SELECT title, 
                scale,
                dense_rank() OVER (PARTITION BY title 
                                       ORDER BY scale ASC) AS r 
           FROM signatures) t
  WHERE r = 1)

...和:

(SELECT scale 
   FROM (SELECT scale,
                dense_rank() OVER (PARTITION BY title 
                                       ORDER BY scale ASC) AS r 
           FROM signatures) t
  WHERE r = 2) 

我正在尝试选择第一个查询 (Q1) 除以第二个查询 (Q2)。即,(来自 Q1 的第 1 行)/(来自第 2 季度的第 1 行)。然后继续往下走。

我试过了:

SELECT ((SELECT scale 
           FROM (SELECT title, 
                        scale,
                        dense_rank() OVER (PARTITION BY title  
                                               ORDER BY scale ASC) AS r 
                   FROM signatures) t
          WHERE r = 1)

/

(SELECT scale 
   FROM (SELECT scale,
                dense_rank() OVER (PARTITION BY title 
                                       ORDER BY scale ASC) AS r 
           FROM signatures) t
  WHERE r = 2) 
)

但是没有运气。 任何人都可以看到这样做的方法吗?我可以分别发送这两个查询,然后运行一个循环并划分元素,但这不适用于半大型记录集。

另外,没关系,但我使用的是 PostgreSQL。

【问题讨论】:

  • 您知道DENSE_RANK 在处理关系时会返回相同的值吗?例如,您可能有三个实例并列第二名,这将在您的部门中引起悲伤...
  • @OMG。好的,但是如果我单独运行查询,我会得到正确的列结果。难道不能在一个语句中划分这两个吗?
  • 我可以定义一个本地临时表来存储每个查询的结果列,然后将它们相乘吗?
  • 后退一步:对于每组具有相同标题的行,您想将最小比例除以下一个最小比例吗?
  • @araqnid:就是这样!我认为dataduck(下面的答案)是在正确的轨道上,但我仍然需要实现它。

标签: php sql postgresql


【解决方案1】:

我认为您想使用LEAD 窗口功能,而不是获得两组并尝试加入它们。这允许您引用同一窗口中的另一行(即具有匹配的partition by)。比如:

select title, scale / next_scale
from ( select title, scale,
              lead(scale) over(partition by title order by scale asc) as next_scale,
              row_number() over(partition by title order by scale asc) as agg_row
       from signatures
     ) agg
where agg_row = 1;

这里,lead(scale)next 行中的 scale 列中获取值以在同一窗口中输出,即按顺序排列的下一个最大比例。我们仍然需要投影row_number() 并对其进行过滤,以便我们只获得每个窗口中第一行的输出行,即每个标题的比例最小的行。

【讨论】:

  • 太棒了!完美运行。我以前没有使用过 LEAD 函数,所以我什至学到了一些新东西;)更不用说查询比运行两个和加入要快得多。非常感谢!
【解决方案2】:

您需要为 SQL 提供某种方式来了解每列中的哪个数字除以哪个数字。试试这个:

    SELECT first.title, (first.scale / second.scale) ratio
      FROM 
           (SELECT scale, title
              FROM (SELECT title, scale,
                           dense_rank() OVER 
                             (PARTITION BY title ORDER BY scale ASC) AS r
                      FROM signatures) t
             WHERE r = 1) first
INNER JOIN
           (SELECT scale, title
              FROM (SELECT title, scale,
                           dense_rank() OVER
                             (PARTITION BY title ORDER BY scale ASC) AS r
                      FROM signatures) t
             WHERE r = 2) second
        ON first.title = second.title

正如 OMG 评论的那样,如果您最终得到几个相同的比例值,DENSE_RANK 可能会给您带来麻烦。如果这适合您的逻辑,您可能希望将每个子查询限制为每个标题一行,或者在外部查询中指定 SELECT DISTINCT,因为重复项将是完全相同的重复项。

【讨论】:

    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多