Выберите только один из отношений один ко многим - PullRequest
0 голосов
/ 28 января 2011

У меня есть таблица, полная событий.Меня попросили создать сводную таблицу сессий;один сеанс может иметь несколько событий.Сессии идентифицируются по одинаковому времени прибытия.Например (это упрощение, я не печатаю фактические метки времени):

EventID  ArrivalTime  StartTime EndTime StaffID
1        0945         0950      0955    John
2        0945         0955      1000    Barb

Может быть преобразовано во что-то вроде:

ArrivalTime StartTime EndTime StaffID
0945        0950      1000    ???

С использованием MIN(StartTime) и MAX(EndTime) чтобы сохранить его в одной строке.

Проблема, с которой я сталкиваюсь, как показывают приведенные выше вопросительные знаки, заключается в получении единого идентификационного номера сотрудника - для какого сотрудника это не имеет большого значения,но мне нужен кто-тоЕсли бы это была просто строка, как я показал выше, это можно было бы сделать с помощью MIN(StaffID), но главное, что мне нужно, это то, что я должен найти StaffID в таблице Staff и вытащить GUID.это связано с коротким кодом, который находится в моей таблице.И GUID не любит такие функции, как MIN().Кроме того, только для усугубления ситуации возможно, что столбец StaffID в таблице «События» имеет значение NULL, поэтому я должен придерживаться левых объединений или аналогичных элементов.

Кто-то предложил подзапрос, но, очевидно, мой мозг отказываетсяпринять это в пятницу и не понять, как заставить это работать.

В качестве основы, вот что-то вроде моего текущего запроса:

SELECT NEWID() AS SessionID,
e.ArrivalTime,
MIN(e.StartTime),
MAX(e.EndTime),
s.StaffGUID
FROM Events e LEFT JOIN Staff s ON e.StaffID = s.StaffID
GROUP BY e.ArrivalTime, s.StaffGUID

Проблема в том,что если в списке есть два разных сотрудника, сессия будет отображаться дважды.Есть идеи?

1 Ответ

2 голосов
/ 28 января 2011

Есть коррелированная опция подвыбора (2000+ для использования TOP):

  SELECT NEWID() AS SessionID,
         e.ArrivalTime,
         MIN(e.StartTime),
         MAX(e.EndTime),
         (SELECT TOP 1 s.StaffGUID
            FROM STAFF s
           WHERE s.staffid = e.staffid) AS staffguid
    FROM EVENTS e
GROUP BY e.arrivaltime, e.staffguid, staffguid

... или производная таблица / встроенное представление (2005+ для использования ROW_NUMBER):

  SELECT NEWID() AS SessionID,
         e.ArrivalTime,
         MIN(e.StartTime),
         MAX(e.EndTime),
         s.staffguid
     FROM EVENTS e
LEFT JOIN (SELECT t.staffid,
                  t.staffguid,
                  ROW_NUMBER() OVER (PARTITION BY t.staffid) AS rank
             FROM STAFF t) s ON s.staffid = e.staffid
                            AND s.rank = 1
 GROUP BY e.arrivaltime, s.staffguid

Я предпочитаю производную таблицу - коррелированные подзапросы, как правило, работают не так хорошо.

...