Как я могу сгруппировать результаты по дням в этом запросе с помощью SQL Server?
у меня есть эта структура таблицы для таблицы дневника:
CREATE TABLE Diary
(
[IdDiary] bigint,
[UserId] int,
[IdDay] numeric(18,0),
[IsAnExtraHour] bit
);
INSERT INTO Diary ([IdDiary], [UserId], [IdDay], [IsAnExtraHour])
values
(51, 1409, 1, 0),
(52, 1409, 1, 1),
(53, 1409, 3, 0),
(54, 1409, 5, 0),
(55, 1409, 5, 1),
(56, 1408, 2, 0);
и эта структура для таблицы DiaryTimetable:
CREATE TABLE DiaryTimetable
(
[IdDiary] bigint,
[Hour] varchar(50)
);
INSERT INTO DiaryTimetable ([IdDiary], [Hour])
VALUES
(51, '09:00'),
(51, '09:30'),
(51, '10:00'),
(51, '10:30'),
(51, '11:00'),
(52, '15:00'),
(52, '15:30'),
(52, '16:00'),
(52, '16:30'),
(52, '17:00'),
(53, '11:00'),
(53, '11:30'),
(53, '12:00'),
(53, '12:30'),
(53, '13:00'),
(54, '10:00'),
(54, '10:30'),
(54, '11:00'),
(54, '11:30'),
(54, '12:00'),
(55, '16:00'),
(55, '16:30'),
(55, '17:00'),
(55, '17:30'),
(55, '18:00'),
(56, '15:00'),
(56, '15:30'),
(56, '16:00'),
(56, '16:30'),
(56, '17:00');
я использовал этот запрос, чтобы получить максимальный час и минимальный час для userid 1409, чтобы получить для каждого дня время, которое входит, и время, которое покидает работу. Idday соответствует номеру дня недели. Например, 1-понедельник, 2-вторник так далее...
SELECT d.IdDiary, d.IdDay, MIN(Hour) as 'Start Time', MAX(Hour) as 'End Time', IsAnExtraHour
FROM Diary AS d
LEFT JOIN DiaryTimetable AS dt ON d.IdDiary = dt.IdDiary
where userid = 1409
GROUP BY d.IdDiary, d.IdDay, IsAnExtraHour
этот запрос дает такой результат:
Я хочу получить такой результат:
Day Start Time End Time Start Extra Time End Extra Time
----- ---------- -------- --------------- ---------------
Monday 09:00 11:00 15:00 17:00
Wednessday 11:00 13:00
Friday 10:00 12:00 16:00 18:00
колонки (IsAnExtraHour) в этой графе указывается, если эта строка имеет лишних часов в день, например, сотрудников начать работать в понедельник в 09:00 до 11:00 и потом снова работает после обеда в 15:00 до 17:00, поэтому я хочу знать, как я могу группа этих часов в том же ряду, надеюсь, я смог выразить четко, я примите предложения спасибо.
4 ответов
SELECT d.IdDay,
MIN(CASE WHEN isAnExtraHour = 0 THEN hour END) as 'Start Time',
MAX(CASE WHEN isAnExtraHour = 0 THEN hour END) as 'End Time',
MIN(CASE WHEN isAnExtraHour = 1 THEN hour END) as 'Start Extra Time',
MAX(CASE WHEN isAnExtraHour = 1 THEN hour END) as 'End Extra Time'
FROM Diary AS d
LEFT JOIN
DiaryTimetable AS dt
ON dt.IdDiary = d.IdDiary
WHERE userid = 1409
GROUP BY
d.IdDay
Я использую код из @Quassnoi и я добавил Это:
SELECT DATENAME(weekday, d.idday-1) as 'Day' ,
MIN(CASE WHEN isAnExtraHour = 0 THEN hour END) AS 'Start Time',
MAX(CASE WHEN isAnExtraHour = 0 THEN hour END) AS 'End Time',
MIN(CASE WHEN isAnExtraHour = 1 THEN hour END) AS 'Start Extra Time',
MAX(CASE WHEN isAnExtraHour = 1 THEN hour END) AS 'End Extra Time'
FROM Diary AS d
LEFT JOIN DiaryTimetable AS dt ON dt.IdDiary = d.IdDiary
WHERE userid = 1409
GROUP BY d.IdDay
Я надеюсь, что это поможет кому-то, спасибо всем за ваши ответы.
то, как я бы подошел к этому, было бы разработать ваши стандартные и дополнительные часы отдельно, что-то вроде этого;
SELECT d.IdDay
,MIN(dt.StartTime) AS 'Start Time'
,MAX(dt.EndTime) AS 'End Time'
,MIN(ex.StartTime) AS 'Start Extra Time'
,MAX(ex.EndTime) AS 'End Extra Time'
FROM Diary AS d
LEFT JOIN (
SELECT IdDiary
,MIN(Hour) AS StartTime
,MAX(Hour) AS EndTime
FROM DiaryTimetable
GROUP BY IdDiary
) AS dt ON d.IdDiary = dt.IdDiary
AND d.IsAnExtraHour = 0
LEFT JOIN (
SELECT IdDiary
,MIN(Hour) AS StartTime
,MAX(Hour) AS EndTime
FROM DiaryTimetable
GROUP BY IdDiary
) AS ex ON d.IdDiary = ex.IdDiary
AND d.IsAnExtraHour = 1
WHERE userid = 1409
GROUP BY d.IdDay
вы сначала можете получить не лишние часы и ушли лишние часы им userId и IdDay. Вот так:
SELECT
CASE BaseHours.IdDay
WHEN 1 THEN 'Monday'
WHEN 2 THEN 'Tuesday'
WHEN 3 THEN 'Wednesday'
WHEN 4 THEN 'Thursday'
WHEN 5 THEN 'Friday'
WHEN 6 THEN 'Saturday'
WHEN 7 THEN 'Sunday'
END AS [WeekDay],
MIN(BaseTimeTable.Hour) as 'Start Time',
MAX(BaseTimeTable.Hour) as 'End Time',
MIN(ExtraTimeTable.Hour) as 'Start Extra Time',
MAX(ExtraTimeTable.Hour) as 'End Extra Time'
FROM Diary AS BaseHours
LEFT JOIN Diary ExtraHours
ON ExtraHours.UserId = BaseHours.UserId
AND ExtraHours.IdDay = BaseHours.IdDay AND ExtraHours.IsAnExtraHour = 1
JOIN DiaryTimetable AS BaseTimeTable
ON BaseHours.IdDiary = BaseTimeTable.IdDiary
LEFT JOIN DiaryTimetable AS ExtraTimeTable
ON ExtraHours.IdDiary = ExtraTimeTable.IdDiary
WHERE BaseHours.Userid = 1409 AND BaseHours.IsAnExtraHour = 0
GROUP BY BaseHours.IdDay