Объединение записей только при первом совпадении

#sql #sql-server #subquery #left-join #case

#sql #sql-сервер #подзапрос #левое соединение #случай

Вопрос:

я пытаюсь соединить две таблицы. Я хочу, чтобы была присоединена только первая совпадающая строка, остальные должны быть нулевыми.

Одна из таблиц содержит ежедневные записи для каждого User пользователя, а вторая таблица содержит цель для каждого пользователя и дня.

Объединенная таблица результатов должна присоединяться только к первому появлению User и Day и устанавливать для остальных значение null . Цель в объединенной таблице может быть интерпретирована как DailyGoal .

Пример:

 Table1                                 Table2
Id   Day          User    Value        Id  Day          User   Goal
================================       ============================
01   01/01/2020   Bob     100          01  01/01/2020   Bob    300
02   01/01/2020   Bob     150          02  02/01/2020   Carl   170
03   01/01/2020   Bob     50           
04   02/01/2020   Carl    200          
05   02/01/2020   Carl    30    

ResultTable
Day          User   Value   Goal 
============================================
01/01/2020   Bob    100     300
01/01/2020   Bob    150     (null)
01/01/2020   Bob    50      (null)
02/01/2020   Carl   200     170
02/01/2020   Carl   30      (null)
 

Я пытался выполнять top1, distinct, подзапросы, но я не могу найти способ сделать это. Возможно ли это?

Ответ №1:

Один из вариантов использует оконные функции:

 select t1.*, t2.goal
from (
    select t1.*,
        row_number() over(partition  by day, user order by id) as rn
    from table1 t1 
) t1
left join table2 t2 on t2.day = t1.day and t2.user = t1.user and t1.rn = 1
 

case Выражение еще проще:

 select t1.*,
    case when row_number() over(partition  by day, user order by id) = 1
        then t2.goal
    end as goal
from table1 t1
 

Комментарии:

1. Спасибо! Я понятия не имею, что partition означает или делает синтаксис, но я изучу его