Разделение в SQL-запросе - PullRequest
       5

Разделение в SQL-запросе

0 голосов
/ 13 января 2011

У меня есть два запроса, которые возвращают один столбец значений двойной точности:

(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). Т.е. (Row1 из Q1) / (Row1 из Q2). И продолжил спуск по остальным рядам.

Я пробовал:

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 ]

1 голос
/ 13 января 2011

Я думаю, что вы хотите использовать оконную функцию 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) берет значение из столбца scale из строки next , которое будет выведено в том же окне, то есть в следующем по величине масштабе по порядку. Нам все еще нужно спроецировать row_number() и отфильтровать его так, чтобы мы просто получали выходные строки для первой строки в каждом окне, то есть строки с наименьшим масштабом для каждого заголовка.

0 голосов
/ 13 января 2011

Вам нужно дать 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 во внешнем запросе, поскольку дубликаты будут точными дубликатами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...