#sql-server
#sql-сервер
Вопрос:
Я работаю над отчетом о устаревании для учетных записей за 30 дней и присоединяюсь к таблице «Комментарий», потому что AP хочет увидеть самый последний комментарий, если он существует для клиента.
Таблица комментариев может содержать несколько строк для одного и того же клиента для каждого комментария, прикрепленного к этому клиенту, причем первая запись является самым старым комментарием.
Когда я присоединяюсь к таблицам, все работает, но он возвращает первый комментарий, а не последний.
Как я могу заставить его искать несколько строк для одного и того же клиента, а затем возвращать самый последний комментарий?
* Примечание — В таблице комментариев нет дат, просто поле начинается с 1000 и увеличивается для каждой новой строки комментария
Это то, что у меня есть прямо сейчас:
SELECT
dbo.[Pioneer-CO$Purchase Header].No_,
dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced],
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date],
dbo.[Pioneer-CO$Comment Line].[Comment],
dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_]
FROM
dbo.[Pioneer-CO$Purchase Header]
INNER JOIN
dbo.[Pioneer-CO$Purchase Line] ON dbo.[Pioneer-CO$Purchase Header].No_ = dbo.[Pioneer-CO$Purchase Line].[Document No_]
INNER JOIN
dbo.[Pioneer-CO$Purch_ Rcpt_ Header] ON dbo.[Pioneer-CO$Purchase Header].No_ = dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Order No_]
INNER JOIN
dbo.[Pioneer-CO$Comment Line] ON dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_] = dbo.[Pioneer-CO$Comment Line].[No_]
WHERE
(dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date] < DATEADD(day, - 30, GETDATE()))
GROUP BY
dbo.[Pioneer-CO$Purchase Header].No_,
dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced],
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date],
dbo.[Pioneer-CO$Comment Line].[Comment],
dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_]
HAVING
(dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced] > '0')
ORDER BY
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date] DESC
Комментарии:
1. Помимо описанной вами проблемы, имейте в виду, что, поскольку вы используете только ВНУТРЕННИЕ объединения, если у клиента вообще нет комментариев, они не будут отображаться в отчете, независимо от того, сколько лет их задолженности.
2.
[posting date] desc
вернет первую / последнюю строку, поскольку по убыванию означает «самая новая первая». попробуйтеasc
вместо этого — сначала самый старый
Ответ №1:
Я бы использовал что-то вроде этого
select customer.*, lastComment.*
from account
cross apply (select top 1 * from comment where
comment.customerId=customer.customerId order by commentnumber desc) lastComment
where customer.age>30
Если вам нужно включить клиентов без комментариев, используйте outer apply
вместо cross apply
Ответ №2:
Я бы использовал следующий запрос:
OUTER APPLY
(select top 1 [Comment] from dbo.[Pioneer-CO$Comment Line] where dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_] = dbo.[Pioneer-CO$Comment Line].[No_] order by [Posting Date] desc) Comments
Кроме того, используйте Comments.[Comment]
в инструкции SELECT вместо dbo.[Pioneer-CO$Comment Line].[Comment]
dbo.Таблица [Pioneer-CO$Comment Line] должна быть ВНЕШНЕЙ, ПРИМЕНЯЮЩЕЙ соединение в запросе. Кроме того, упорядочивайте комментарии по дате публикации или добавочному идентификатору.
Ответ №3:
Вы должны посмотреть на идентификатор или первичный ключ, я бы предположил, что более новые комментарии имеют более высокий идентификатор. Вы могли бы объединить таблицы и выполнить Max (ID) или искать последнюю временную метку, если вы используете ее в своей таблице.
Комментарии:
1. Я довольно новичок в SQL, и у меня возникли проблемы с использованием функции MAX. Есть предложения о том, как будет выглядеть этот код?
2. Поиск @Rkindred MAX — MSDN . MSDN от Microsoft — отличный ресурс по синтаксису и официальному использованию ключевых слов SQL. Кроме того, поймите, что если функция не выполняется сама по себе, у вас ДОЛЖЕН быть столбец (неагрегированный), который появляется в
SELECT
, также появляется вGROUP BY
предложении. Обзор со ссылками на другие агрегаты см. в разделе АГРЕГАТНЫЕ ФУНКЦИИ — MSDN
Ответ №4:
Похоже, у вас отношение клиентов к комментариям равно 1 ко многим (0). Как насчет того, чтобы попробовать что-то вроде этого,
SELECT TOP 1 Customers.*, Comments.*
FROM Customers
JOIN Customers ON Customers.Id = Comments.Id
ORDER BY Comments.Id DESC
Следующее добавлено после комментариев Bib
Вы также можете попробовать следующее
SELECT Customers.*, Comments.*
FROM Comments
JOIN
(SELECT MAX(Id) As CId FROM Comments GROUP BY CustomerId) AS CommentsMAX
ON CommentsMAX.CId = Comments.ID
JOIN
Customers ON Customers.Id = Comments.Id
Комментарии:
1. Это вернет только одну строку, это будет последний комментарий и клиент, с которым связан этот комментарий