Выберите идентификатор наименьшей строки в группе, используя SQL Compact Edition - PullRequest
2 голосов
/ 16 ноября 2011

Мой вопрос похож на: Как группировать по одному столбцу и получать строку с минимальным значением другого столбца в T / SQL?

Прежде всего: я использую SQL Server Compact, что делает SQL довольно ограничительным.

У меня есть две таблицы и связь между многими: комнаты и курсы. Из списка комнат я хочу проверить, свободна ли комната в указанный промежуток времени, какой курс сейчас находится в этой комнате и какой следующий курс в этой комнате. Первые две части без проблем:

SELECT a.Id, COUNT(c.Id) AS ConflictingCourses, d.Id AS CurrentCourseId
FROM Rooms AS a 
    LEFT OUTER JOIN RoomCourses AS b ON b.RoomId = a.Id
    -- Conflicting Courses
    LEFT OUTER JOIN Courses AS c ON c.Id = b.CourseId AND @startTime <= c.EndTime AND @endTime >= c.StartTime
    -- Current Course  
    LEFT OUTER JOIN Courses AS d ON d.Id = b.CourseId AND @now <= d.EndTime AND @now >= d.StartTime 
WHERE (a.Id IN (1,2,3,4))
GROUP BY a.RoomId, d.Id

Теперь к проблеме: я хочу получить первый курс, который имеет StartTime после этого. Чтобы пройти этот курс, я стараюсь присоединиться ко всем последующим курсам. Из этого результата я подумал, что будет легко получить следующий курс, потому что для каждой группы это идентификатор строки с наименьшей датой:

SELECT a.Id, COUNT(c.Id) AS ConflictingCourses, d.Id AS CurrentCourseId
FROM Rooms AS a 
    LEFT OUTER JOIN RoomCourses AS b ON b.RoomId = a.Id
    -- Conflicting Courses
    LEFT OUTER JOIN Courses AS c ON c.Id = b.CourseId AND @startTime <= c.EndTime AND @endTime >= c.StartTime
    -- Current Course  
    LEFT OUTER JOIN Courses AS d ON d.Id = b.CourseId AND @now <= d.EndTime AND @now >= d.StartTime 
    -- All Upcoming Courses
    LEFT OUTER JOIN Courses AS e ON e.Id = b.CourseId AND e.StartTime >= @now
WHERE (a.Id IN (1,2,3,4))
GROUP BY a.RoomId, d.Id

Но я могу получить только время начала следующего курса, используя MIN (e.StartTime). Но я хочу идентификатор строки, которой принадлежит MIN (e.StartTime). Я перепробовал сотни комбинаций, обходных путей и прочего, чтобы получить идентификатор предстоящего курса. Основная проблема заключается в том, что SQL CE не поддерживает подзапросы, которые возвращают скалярные значения, и поэтому я не могу получить какую-либо информацию, которая позволила бы мне получить только следующий курс.

Какие-нибудь идеи, как я мог бы получить предстоящий курс комнаты?

1 Ответ

0 голосов
/ 17 декабря 2011

Вы пробовали следующее?

SELECT a.Id, COUNT(c.Id) AS ConflictingCourses, d.Id AS CurrentCourseId
FROM Rooms AS a 
    LEFT OUTER JOIN RoomCourses AS b ON b.RoomId = a.Id
    -- Conflicting Courses
    LEFT OUTER JOIN Courses AS c ON c.Id = b.CourseId AND @startTime <= c.EndTime AND @endTime >= c.StartTime
    -- Current Course  
    LEFT OUTER JOIN Courses AS d ON d.Id = b.CourseId AND @now <= d.EndTime AND @now >= d.StartTime 
    -- All Upcoming Courses
    LEFT OUTER JOIN Courses AS e ON e.Id IN (SELECT MIN(Id) 
                                             FROM Courses
                                             WHERE Id = b.CourseId
                                               AND e.StartTime >= @now)
WHERE (a.Id IN (1,2,3,4))
GROUP BY a.RoomId, d.Id

Я знаю, что IN здесь бесполезен, поскольку запрос всегда будет возвращать только 1 результат, но, очевидно, это обходной путь для такой ситуации (SQL CE).

...