Проблема с моим SQL-соединением / групповым вопросом / курсором - PullRequest
2 голосов
/ 21 января 2010

Я сделал дизайн базы данных для небольшой системы CRM. Он состоит из компаний и собраний (среди прочих).

Компания имеет поля: ID (основной, auto_inc) Имя (текст)

Встречи имеет поля: ID (основной, auto_inc) CompanyId (ссылка на Companies.ID) WhenTime (дата и время, чтобы сохранить, когда встреча была) Заметки (текст о встрече)

То, что я хочу выполнить, - это запрос, который дает мне список всех компаний (все поля в таблице), И Время и Примечания последней встречи с этой компанией (последняя - это максимум (Когда время), и если есть Нет, NULL подойдет).

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

Я попробовал несколько составов Group By, но боюсь, что мне не хватает изящества.

Моя последняя попытка была такой:

select Companies.ID, Companies.name, mts.whentime, mts.notes
from Companies
left outer join (
    select top(1) *
    from Meetings
    order by [whentime] desc
) mts
on Companies.ID = mts.companyID
order by Companies.name asc

но этот код принимает только один кортеж от Meetings, а не один на каждую компанию в объединении, так что это бесполезно.

Есть идеи?

Ответы [ 3 ]

2 голосов
/ 21 января 2010

Я бы начал с создания представления последних собраний, так как создание представлений упрощает чтение и обслуживание сложных запросов и может вводить элемент повторного использования (если все сделано правильно).

CREATE VIEW [dbo].[LatestCompanyNotes]
AS

SELECT [CompanyId], [WhenTime], [Notes]
FROM [Meetings] AS M1
INNER JOIN 
    (
        SELECT [CompanyId], MAX([Id]) AS [MaxId]
        FROM [Meetings]
        GROUP BY [CompanyId]
    ) AS M2 ON M2.[CompanyId] = M1.[CompanyId] AND M2.[MaxId] = M1.[Id]

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

SELECT Companies.[ID], Companies.[Name], mts.[WhenTime], mts.[Notes]
FROM [Companies]
    LEFT OUTER JOIN [dbo].[LatestCompanyNotes] AS mts ON mts.[CompanyId] = Companies.[ID]
ORDER BY Companies.[Name] ASC

Обратите внимание, что я не тестировал код (у меня даже не установлен SQL Server), и для его работы может потребоваться несколько небольших изменений.

2 голосов
/ 21 января 2010

Попробуйте:

select Companies.ID, Companies.name, mts.whentime, mts.notes
from Companies
cross apply 
(
    select top(1) *
    from Meetings
    where Companies.ID = Meetings.companyID
    order by [whentime] desc
) mts
order by Companies.name asc;
1 голос
/ 21 января 2010

Здесь вам не нужно перекрестное применение, просто коррелированный подзапрос, чтобы найти самую последнюю дату встречи:

SELECT Companies.ID, Companies.name, mts.whentime, mts.notes
FROM Companies
LEFT OUTER JOIN Meetings mts
ON Companies.ID = mts.companyID
AND mts.WhenTime =
 (SELECT MAX(WhenTime) FROM Meetings mtshist WHERE mtshist.companyID = mts.companyID)
ORDER BY Companies.name

Обратите внимание, что при этом будут извлечены все компании, в том числе те, которые никогда не встречались:

1 Alexander and co.   2010-01-04 some more notes
2 Barnard Partnership 2010-01-03 NULL
3 Collingwood Ltd.    2010-01-07 recent meeting
4 Dimitri and sons    NULL       NULL
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...