Запрос к базе данных во время цикла - PullRequest
1 голос
/ 20 июля 2011

Я на 99% уверен, что этот вопрос задавался 100 раз, но я не могу найти что-нибудь на SO о том, как лучше всего это сделать.

У меня есть таблица с именем People, затем таблицаназывается Jobs, в котором хранится вся их история трудоустройства.

При создании отчетов, сводных панелей и т. д. он встречается довольно часто, где мы хотим перечислить каждого человека и его последние 3 вакансии (например):

Джон Смит

  • Некоторая компания, 4/3 / 2011-5 / 14/2011
  • Другая компания, 3/12 / 2010-4 / 1/2011
  • Другая компания, 8/1 / 2009-1 / 4/2010

Салли Смитерс

  • Некоторая компания, 4/3 / 2011-5 / 14 /2011
  • Другая компания, 3/12 / 2010-4 / 1/2011
  • Другая компания, 8/1 / 2009-1 / 4/2010

И т. Д.

Какой-то псевдокод VBish:

SELECT PersonID, Name FROM People

Do While datareaderPeople.Read()
   Response.write(datareaderPeople("Name")
   'SELECT TOP 3 PersonID, JobID, CompanyName, OtherFields FROM Jobs WHERE PersonID = datareaderPeople("PersonID") ORDER BY SomeDateField
   Do While datareaderJobs.Read()
       Response.write(datareaderJobs("CompanyName"))
   End While
End While

Как вы можете видеть, в настоящее время мы делаем еще один запрос, чтобы получить задания для каждого человека, пока мы перебираем людей.Есть лучший способ сделать это?Этот способ кажется неэффективным и создает много запросов к базе данных.

Или, если кто-то может указать мне на этот вопрос, заданный ранее, это тоже было бы хорошо.

Спасибо.

Edit: Я использую описанный выше метод, потому что мне нужно иметь возможность делать что-то с полями Jobs для каждой строки Jobs, которую я получаю обратно.Например, форматирование даты, выделение жирным шрифтом названия компании и т. Д. Просто вернуть одну большую строку с полями Джобса, объединенными в одну большую строку, не получится.

Ответы [ 2 ]

2 голосов
/ 20 июля 2011

Предполагая SQL Server 2005 или выше:

SELECT  *
FROM    people p
OUTER APPLY
        (
        SELECT  TOP 3 *
        FROM    job j
        WHERE   j.personId = p.id
        ORDER BY
                j.applicationDate DESC
        ) j

или это:

SELECT  *
FROM    (
        SELECT  *,
                ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY j.appicationDate DESC) AS rn
        FROM    people p
        LEFT JOIN
                job j
        ON      j.personId = p.id
        ) q
WHERE   rn <= 3
1 голос
/ 20 июля 2011

Я предлагаю вам сделать следующее, и это будет только 2 вызова базы данных

SELECT PersonID, Name FROM People
SELECT PersonID, JobID, CompanyName, OtherFields FROM Jobs

Do While datareaderPeople.Read()
   Response.write(datareaderPeople("Name")
   Filter Jobs records data with DataView using RowFilter = "PersonID = " + datareaderPeople("PersonID")

   Do While FilteredRows.Read()
       Response.write(FilteredRows("CompanyName"))
   End While
End While
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...