2013-09-16 4 views
0

Я относительно новичок в SQL и postgres. Я имею отношение R1 и R2 с несколькими столбцами, каждое из которых является некоторым измерением, например R1.m и R2.m. Теперь мне нужно найти для каждой строки в R1 минимальную некоторую функцию f (R1.m и R2.m), f(R1.m,R2.m) так, чтобы код был чем-то вроде select R1.name, R2.name from R1,R2 where f(R1.m,R2.m) < ........ Я не могу заполнить этот запрос. Мне нужна строка R2 для каждой строки в R1, которая минимизирует функцию. Я знаю, что это просто, просто не справитесь с новичком. (В Postgres)Простой SQL-запрос кадрирования

+0

Возможно, вы захотите немного рассказать об этой функции, которую вы пытаетесь сделать. Не совсем понятно, что вы хотите достичь –

ответ

0

Если я понимаю, что

select distinct on (r1.name) 
    r1.name, r2.name, f(r1.m, r2.m) 
from r1 cross join r2 
order by r1.name, f(r1.m, r2.m) 

distinct on будет возвращать одно только r1.name, первый вычисленный из пункта order by.

0

Не уверен, что я undrestand ваш вопрос правильно, попробуйте что-то вроде этого:

with 

r1 as (select generate_series(1,10,1) as m) 
,r2 as (select generate_series(10,20,1) as m) 

,cte as (
    select 
     r1.m as "r1.m", 
     r2.m as "r2.m", 
     sin(r1.m * r2.m) f_r1r2, 
     dense_rank() over (partition by r1.m order by sin(r1.m * r2.m)) as f_r1r2_rank 
    from 
     r1, 
     r2 
    ) 

select 
    * 
from 
    cte 
where 
    f_r1r2_rank = 1 

Это будет:

  1. Создать перекрестный продукт или r1 и r2 (получить все возможные комбинации r1.m и r2.m)
  2. Рассчитать функцию f (в моем случае я использовал sin(r1.m*r2.m) в качестве примера)
  3. Вычислить ранг для каждого набора комбинации r1 и r2
  4. Выберите только те, где ранг = 1 (минимум)

Другими словами, это будет ответить на вопрос: «Что r2.m я должен использовать, чтобы получить минимум функции f(r1.m,r2.m)r1.m? ".

Поскольку вы не предоставили образцы данных, я создал свой собственный. Для того, чтобы заставить его работать, вы должны использовать что-то вроде:

with  
cte as (
    select 
     r1.m as "r1.m", 
     r2.m as "r2.m", 
     sin(r1.m * r2.m) f_r1r2, 
     dense_rank() over (partition by r1.m order by sin(r1.m * r2.m)) as f_r1r2_rank 
    from 
     r1, 
     r2 
    ) 

select 
    * 
from 
    cte 
where 
    f_r1r2_rank = 1 

и, конечно же, вы должны заменить sin(r1.m * r2.m) с вашей собственной функции.

Смежные вопросы