Sql заявление помочь - PullRequest
       1

Sql заявление помочь

4 голосов
/ 01 сентября 2011

Я работаю над Gridview на ASP .Net.У меня есть таблица в SQL Server, которая имеет столбцы с именами «Фамилия» и «Дата» (DateTime) и продолжительность.Таблица для запросов на отпуск.Как я могу построить оператор SQL, чтобы увидеть, сколько людей будет отсутствовать за каждый день?Дело в том, что запрос SELECT [Date], COUNT(DISTINCT surname) GROUP BY [Date] не покажет мне, что на самом деле 8 человек пропадут без вести 2 сентября.Например, учитывая следующие данные:

surname Date       Duration
------- ---------- ---------
Bertram 2011-09-01     3
Coulois 2011-09-01     5
LeBlanc 2011-09-01     6
Fosters 2011-09-01     3
Blanche 2011-09-01     2
Bertram 2011-09-02     6
Gillian 2011-09-02     4
Pikklar 2011-09-02     7
Thierry 2011-09-03     6
Selanne 2011-09-03     6

Я хочу получить следующие результаты:

Date  Count
----- -----
1 Sep     5
2 Sep     8    
3 Sep     10

Есть какие-нибудь идеи, как подойти к нему и получить представление сетки с этими данными ?.Спасибо за ваше время

Ответы [ 4 ]

3 голосов
/ 01 сентября 2011

Вы можете сделать это, используя таблицу чисел . Здесь я использую master..spt_values.

declare @T table
(
  surname varchar(20),
  [Date] datetime,
  Duration int
)

insert into @T values
('Bertram', '2011-09-01',     3),
('Coulois', '2011-09-01',     5),
('LeBlanc', '2011-09-01',     6),
('Fosters', '2011-09-01',     3),
('Blanche', '2011-09-01',     2),
('Bertram', '2011-09-02',     6),
('Gillian', '2011-09-02',     4),
('Pikklar', '2011-09-02',     7),
('Thierry', '2011-09-03',     6),
('Selanne', '2011-09-03',     6)


select dateadd(day, N.number, [Date]) as [Date],
       count(*) as [Count]
from @T as T
  inner join master..spt_values as N
    on N.number between 0 and T.Duration
where N.type = 'P'    
group by dateadd(day, N.number, [Date])
order by dateadd(day, N.number, [Date])

Результат:

Date                    Count
----------------------- -----------
2011-09-01 00:00:00.000 5
2011-09-02 00:00:00.000 8
2011-09-03 00:00:00.000 10
2011-09-04 00:00:00.000 9
2011-09-05 00:00:00.000 7
2011-09-06 00:00:00.000 7
2011-09-07 00:00:00.000 5
2011-09-08 00:00:00.000 4
2011-09-09 00:00:00.000 3
2 голосов
/ 01 сентября 2011

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

2011-09-01  5
2011-09-02  8
2011-09-03  10
2011-09-04  9
2011-09-05  7
2011-09-06  7
2011-09-07  5
2011-09-08  4
2011-09-09  3

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

DECLARE @MaxDate date
SELECT  @MaxDate = max(dateAdd(day, duration, date)) 
FROM holiday;

WITH HolidayDates (holidayDate)
as
(
    SELECT  MIN(date) holidayDate 
    FROM    holiday 
    UNION ALL 
    SELECT  DateAdd(day, 1, holidayDate)
    FROM    holidayDates 
    WHERE   holidayDate <@MaxDate
)

SELECT      cast(hd.holidayDate as date) holidayDate
            , count(h.surname) PeopleOnHoliday
FROM        HolidayDates hd
LEFT JOIN   holiday h on hd.holidayDate between h.date AND dateAdd(day, duration, date) 
GROUP BY    hd.holidayDate
ORDER BY    hd.holidayDate

надеюсь, это поможет ...

2 голосов
/ 01 сентября 2011

Вы можете попробовать что-то вроде этого

WITH Dates AS
    (SELECT CAST('9/1/2011' AS DATE) AS [DATE]
    UNION SELECT '9/2/2011'
    UNION SELECT '9/3/2011'
    )

SELECT [DATE], SUM(OnVacation) AS COUNT
FROM
    (
    SELECT [DATE], 
        CASE WHEN [DATE] BETWEEN StartDate AND DATEADD(dd, Duration, StartDate) 
             THEN 1 ELSE 0 END AS OnVacation
    FROM Vacations
    CROSS JOIN Dates
    ) x
GROUP BY [DATE]
ORDER BY [DATE]

Таблица Даты будет таблицей, в которой есть список дат, которые вы хотите просмотреть. Это общее табличное выражение (CTE) в этом запросе.

Это также предполагает, что датой начала является первый день продолжительности.

1 голос
/ 01 сентября 2011

Мне нравится Бобс ответить Справка по Sql .

Вот CTE, в котором вам нужно создать столбец дат с указанием даты начала и окончания.

DECLARE @start datetime = '2011-01-01'
DECLARE @end datetime = '2011-01-31'

; WITH Dates as
(
    SELECT @start as d
    UNION ALL 
    SELECT DATEADD(DAY, 1, d)FROM dates WHERE d < @end
)
SELECT * FROM Dates

Если вы включите это в свой ответ и создадите хранимую процедуру, которая принимаетпараметры 'start' и 'end, у вас должен быть свой ответ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...