Как вернуть одну строку из объединенной таблицы

#sql #sql-server #inner-join

#sql #sql-сервер #внутреннее соединение

Вопрос:

Тип поля:

 Date1 = varchar(10)
Date2 = int
  

Таблицы:

 tblName

Num(pk)         Name            Open
0909            John Doe        Yes
0908            Jason Kelly     Yes


tblOwes

Num(pk)     Date1           Date2           Amnt        Type
0909        11/14/2020      20201114        350.00      12
0909        11/15/2020      20201115        250.00      12
0909        10/29/2020      20201029        650.00      13
0909        09/12/2020      20200912        898.00      12
0908        08/29/2020      20200829        650.00      12
0908        09/15/2020      20200915        250.00      12
0908        09/14/2020      20200914        350.00      12
0908        08/12/2020      20200812        898.00      13
  

Запрос:

 select tn.Num, tn.Name, to.Date1, to.Amnt
from tblName tn
inner join tblOwes to
    on tn.Num = to.Num
where to.Date1 = (select top 1 to.Date1 from tblOwes where to.Num = tn.Num order by to.Date1 Desc)
  

Мне нужна только одна запись tblOwes , самая последняя по Date1 столбцу, для каждой учетной tblName записи, где тип равен 12, а Open — Да

Желаемый результат:

 Num     Name            Date1       Amnt        Type        Open
0909    John Doe        11/15/2020  250.00      12          Yes
0908    Jason Kelly     09/15/2020  250.00      12          Yes
  

Прямо сейчас он возвращает четыре записи для Джона и четыре для Джейсона

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

1. Какую СУБД вы используете? (Этот запрос зависит от продукта.)

2. Извините, СУБД SQL

3. Какую? MS SQL Server?

4. ДА… Итак, я должен обновить? потому что я тоже должен проверять наличие других столбцов.

Ответ №1:

Простой метод использует row_number() :

 select tn.Num, tn.Name, o.Date1, o.Amnt
from tblName tn join
     (select o.*, 
             row_number() over (partition by o.num order by o.date1 desc) as seqnum
      from tblOwes o
     ) o
     on tn.Num = o.Num and seqnum = 1;
  

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

1. Хммммм это в SQL?

2. да, это SQL, и я думаю, что Гордону не хватает условия для объединения : AND o.seqnum = 1

Ответ №2:

Возможно, это тот запрос, который вы ищете

 with o_cte as (
    select *, row_number() over (partition by num order by date1 desc) as rn
    from tblOwes
    where [Type]=12)
select n.Num, t.[Name], o.Date1, o.Amnt, o.[Type], n.[Open]
from tblName n
     join o_cte o on n.Num = o.Num
where n.[Open]='Yes'
      and o.rn=1
order by n.Num desc;
  

С другой стороны, если это ‘Name’ из таблицы tblNames, которая уникальна (по ‘num’), тогда РАЗДЕЛ BY будет n.[Name] и запрос могут выглядеть следующим образом

 with o_cte as (
    select o.*, row_number() over (partition by n.[Name] order by date1 desc) as rn
    from tblName n
         join tblOwes o on n.Num = o.Num
    where o.[Type]=12
          and n.[Open]='Yes')
select n.Num, t.[Name], o.Date1, o.Amnt, o.[Type], n.[Open]
from tblName n
     join o_cte o on n.Num = o.Num
where 
      and o.rn=1
order by n.Num desc;
  

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

1. Я пробовал это, но я получаю неизвестные четыре записи из результата, потому что в tblOwes четыре записи

2. Спасибо за помощь. Я нацелился на tblOwes и смог присоединиться с помощью tblName, и это сработало как шарм. Даже не нужно было использовать CTE! Оцените это еще раз 1