BeginnerCoderPete Ответов: 2

Как выбрать последнюю запись в сравнении с другой записью таблиц для каждого клиента в SQL?


У меня есть три таблицы в SQL:

tblCustomers
    pkCustomer <-- linked to fkCustomer
    strCustomerName

tblCommunicationsLogs
    pkCommunicationLog
    fkCustomer

tblCommunicationLogSteps
    pkCommunicationLogStep
    fkCommunicationLog <-- linked to pkCommunicationLog
    strCommunicationLogStep


У каждого клиента есть журнал связи, в который записываются шаги связи.

Я хотел бы создать представление для отображения последнего шага журнала для каждого клиента.

Но я просто не могу понять, как написать запрос.

Что я уже пробовал:

Я пробовал гуглить примеры, но на самом деле я не очень хорошо разбираюсь в SQL и просто недостаточно понимаю его.

Я знаю, что пытался сделать это в прошлом и был близок к этому, но теперь я не могу вспомнить, что я сделал, чтобы продолжать это.

Я предполагаю, что это похоже на SELECT MAX из tblCommunicationLogSteps, где pkCommunicationLog = fkCommunicationLog в tblCommunicationSteps, и, возможно, группа по клиенту?? но я просто не знаю.

#realJSOP

Нам нужно видеть столбцы для каждой таблицы.

BeginnerCoderPete

tblCommunicationsLogs
pkCommunicationLog
fkCustomer

tblCommunicationLogSteps
pkCommunicationLogStep
fkCommunicationLog <-- связан с pkCommunicationLog
strCommunicationLogStep

tblCustomers
pkCustomer <-- связан с fkCustomer
strCustomerName

#realJSOP

Используйте ссылку "улучшить вопрос", чтобы изменить свой вопрос.

Как определить последнюю запись шага журнала, если нет столбца datetime, указывающего, когда этот шаг был вставлен в таблицу?

BeginnerCoderPete

Я думал, что самые высокие pkCommunicationLogSteps, связанные с журналом, дадут мне последний шаг в этом журнале.

CHill60

Этот fkCommunicationsLog в tblCustomers подразумевает, что каждый клиент может иметь только одну запись журнала tblCommunication ... неужели это правда?

BeginnerCoderPete

Ваше право, это была моя ошибка, что в таблице нет fkCommunicationsLog. Моя ошибка.

0x01AA

Я бы предложил использовать CROSS APPLY:
SQL Server CROSS APPLY и OUTER APPLY[^]

...но не уверен, что он действительно работает над двумя соединениями :(

2 Ответов

Рейтинг:
9

Wendelius

В данный момент у вас нет редактора SQL, поэтому, пожалуйста, извините за любые опечатки. А как насчет чего-то вроде

SELECT *
FROM tblCustomers c,
     tblCommunicationsLog cl,
     tblCommunicationLogSteps cls
WHERE cl.fkCustomer = c.pkCustomer
AND   cls.fkCommunicationLog = cl.pkCommunicationLog
AND   cls.pkCommunicationLogStep =
                 (SELECT MAX(cls2.pkCommunicationLogStep)
                  FROM   tblCommunicationLogSteps cls2
                  WHERE cls2.fkCommunicationLog = cl.pkCommunicationLog)

Или немного другой вариант
SELECT *
FROM tblCustomers c,
     tblCommunicationsLog cl,
     tblCommunicationLogSteps cls
WHERE cl.fkCustomer = c.pkCustomer
AND   cls.fkCommunicationLog = cl.pkCommunicationLog
AND   NOT EXISTS (SELECT 1
                  FROM   tblCommunicationLogSteps cls2
                  WHERE cls2.fkCommunicationLog = cl.pkCommunicationLog
                  AND   cls2.pkCommunicationLogStep > cls.pkCommunicationLogStep)

Просто убедитесь, что вы проиндексировали столбцы внешнего ключа.


BeginnerCoderPete

Абсолютно точно, большое спасибо!

Wendelius

Всегда пожалуйста :)

Рейтинг:
1

CHill60

Я думаю, что эти идеи работают... немного "грубой силы" и обратите внимание, что использование подзапросов не является самым эффективным (но это отправная точка :-) )

Чтобы получить инструкции для самой последней записи журнала связи:

select pkCustomer, strCustomerName, pkCommunicationLog, pkCommunicationLogStep, strCommunicationLogStep
from #tblCustomers C
left join #tblCommunicationsLogs L ON L.fkCustomer = c.pkCustomer
left join #tblCommunicationLogSteps S on S.fkCommunicationLog = L.pkCommunicationLog
inner join (SELECT MAX(pkCommunicationLog) as m, fkCustomer FROM #tblCommunicationsLogs GROUP BY fkCustomer) as fltr ON fltr.m=L.pkCommunicationLog
ORDER BY pkCommunicationLog,pkCommunicationLogStep
Чтобы получить только самый последний журнал шаг за шагом клиент
select pkCustomer, strCustomerName, pkCommunicationLog, pkCommunicationLogStep, strCommunicationLogStep
from #tblCustomers C
left join #tblCommunicationsLogs L ON L.fkCustomer = c.pkCustomer
left join #tblCommunicationLogSteps S on S.fkCommunicationLog = L.pkCommunicationLog
inner join (SELECT MAX(pkCommunicationLogStep) as m, fkCommunicationLog FROM #tblCommunicationLogSteps GROUP BY fkCommunicationLog) as fltr ON fltr.m=S.pkCommunicationLogStep AND fltr.fkCommunicationLog = S.fkCommunicationLog
ORDER BY pkCommunicationLog,pkCommunicationLogStep


0x01AA

Пока что 5. Любая идея, будь то крест применить будет работать для этого и может быть более производительным?

CHill60

Без понятия. К сожалению, я уже выгрузил данные в мусорное ведро

BeginnerCoderPete

Запрос отсчитывает время, но это определенно толчок в правильном направлении, который я очень ценю. Я также поставил SELECT TOP (10), но все равно тайм-аут, что странно.