在SQL查询语句中划分

时间:2011-01-13 16:40:41

标签: php sql postgresql

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

(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的Row1)/(来自Q2的Row1)。然后继续沿着剩下的行。

我试过了:

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。

2 个答案:

答案 0 :(得分: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()进行投影并对其进行过滤,以便我们只获取每个窗口中第一行的输出行,即每个标题的缩放比例最小的行。

答案 1 :(得分:0)

你需要给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,因为重复项将完全重复。