2015-01-28 3 views
1

Если у меня есть данные, хранящиеся в db, так и так.Количество экземпляров во временном интервале в SQL

fk start end 
1  1000  1100 
1  1030  1130 
2  1000  1100 

Как я могу написать мой запрос, так что я могу получить результат, как:

fk timeslot occurences 
1  1000  1 
1  1030  2 
1  1100  1 
2  1000  1 
2  1030  1 

Как вы можете сказать, что я работаю с шагом 30 мин. Я могу достичь этой серверной части, но она требует, чтобы я либо запускал запрос запросов, либо каждый раз попадал в БД, подсчитывая строки между ними два раза. Если я смогу собрать эту информацию в 1 запросе, вся моя система будет намного быстрее.

FK - это идентификатор моего ресурса, который зарезервирован.

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

Вы также можете предположить, что для fk 1 и 2 у меня есть известное максимальное время запуска и максимальное конечное время, если это имеет значение.

+1

Так что вы пробовали? –

+0

Я пробовал делать это на стороне сервера, и я знаю, что смогу. Я спрашиваю, можно ли сделать это в MSSQL. Я не знаю, с чего начать в SQL. Я думаю, что это можно сделать с помощью операторов CASE, но было бы так же, как 48 из них, что неэффективно. – Leeish

+0

Не знаете, как вы получили 'timeslot' в результате –

ответ

1

Вы должны как-то создать все временные интервалы сначала, чтобы у вас есть sth, по которым можно проверить бронирование. Рекурсивный CTE в основном подходит для этого типа. Таким образом, использование может использовать эту CTE:

DECLARE @MinStart TIME = '10:00:00' 
DECLARE @MaxEnd TIME = '12:00:00' 

;WITH Timeslots AS (
    SELECT SlotStart = @MinStart, 
      SlotEnd = DATEADD(MINUTE, 30, @MinStart) 

    UNION ALL 

    SELECT SlotStart = DATEADD(MINUTE, 30, SlotStart), 
      SlotEnd = DATEADD(MINUTE, 30, SlotEnd) 
    FROM Timeslots 
    WHERE SlotEnd < @MaxEnd 
) 
SELECT * 
FROM Timeslots 

генерировать следующее выражение таблицы:

SlotStart   SlotEnd 
------------------------------------ 
10:00:00.0000000 10:30:00.0000000 
10:30:00.0000000 11:00:00.0000000 
11:00:00.0000000 11:30:00.0000000 
11:30:00.0000000 12:00:00.0000000 

Это все временные интервалы между 10:00 и 12:00.

Теперь вы можете использовать этот запрос:

;WITH Timeslots AS (
    ... cte statement here ... 
) 
SELECT fk, COUNT(fk) AS occurrences, t.SlotStart, t.SlotEnd 
FROM #Reservations AS r 
INNER JOIN Timeslots AS t ON t.SlotStart >= r.start AND t.SlotEnd <= r.[end] 
GROUP BY fk, t.SlotStart, t.SlotEnd 

, чтобы получить результат, который вы хотите:

fk occurrences SlotStart   SlotEnd 
--------------------------------------------- 
1 1   10:00:00.0000000 10:30:00.0000000 
1 2   10:30:00.0000000 11:00:00.0000000 
1 1   11:00:00.0000000 11:30:00.0000000 
2 1   10:00:00.0000000 10:30:00.0000000 
2 1   10:30:00.0000000 11:00:00.0000000 
+0

Собираюсь попробовать это сегодня. Благодарю. Никогда раньше не использовал «С», и не знал, что он существует. – Leeish

Смежные вопросы