xpertzgurtej Ответов: 2

Как получить минимальную и максимальную запись из каждой группы


Образец таблицы

Объявите таблицу @tb(UserId INT, InOutDateTime DATETIME , AttendanceType CHAR(1))

Вставить в @tb значения (1,'2017-08-18 08:00:00.000','я')
Вставить в @tb значения (1,'2017-08-18 07:00:00.000','я')
Вставить в @tb значения (1,'2017-08-18 11:00:00.000','о')
Вставить в @tb значения (1,'2017-08-18 23:00:00.000','я')

Вставить в @tb значения (1,'2017-09-18 06:00:00.000','я')
Вставить в @tb значения (1,'2017-09-18 22:00:00.000','о')
Вставить в @tb значения (1,'2017-09-18 19:00:00.000','я')

Вставить в @tb значения (3,'2017-08-18 09:00:00.000','я')
Вставить в @tb значения (3,'2017-08-18 15:00:00.000','о')
Вставить в @tb значения (3,'2017-08-18 13:00:00.000','о')
Вставить в @tb значения (3,'2017-08-18 23:00:00.000','я')

выберите * из @tb

Мне нужно минимальное InOutDateTime и максимальное InOutDateTime для каждого пользователя на каждую дату. Минимальный InOutDateTime должен быть оттуда, где AttendanceType='I' .
Аналогично максимальное значение InOutDateTime должно быть оттуда, где AttendanceType='O'

Что я уже пробовал:

выберите имя пользователя, мин(InOutDateTime) min_InDateTime, Макс(InOutDateTime) max_OutDateTime
от @группа ТБ на пользователя, литой(InOutDateTime как дата)
Заказ по идентификатору пользователя, литой(InOutDateTime как дата)

Но я не могу получить результаты, основанные на AttendanceType

2 Ответов

Рейтинг:
10

Richard Deeming

Попробуйте что-нибудь вроде этого:

SELECT
    UserId,
    Convert(date, InOutDateTime) As day,
    Min(CASE
        WHEN AttendanceType = 'I' THEN CAST(InOutDateTime As time(0))
        ELSE CAST('23:59:59' As time(0))
    END) As MinInTime,
    Max(CASE
        WHEN AttendanceType = 'O' THEN CAST(InOutDateTime As time(0)) 
    END) As MaxOutTime
FROM
    @tb
GROUP BY
    UserId,
    Convert(date, InOutDateTime)
;
Выход:
UserId  day          MinInTime  MaxOutTime
1       2017-08-18   07:00:00   11:00:00
3       2017-08-18   09:00:00   15:00:00
1       2017-09-18   06:00:00   22:00:00


xpertzgurtej

Это сработало.большое спасибо за ваше время :)

Рейтинг:
1

OriginalGriff

Когда вы ГРУППИРУЕТЕСЬ по, вам, вероятно, нужно использовать предложение HAVING: Использование предложений HAVING и WHERE в одном запросе | Microsoft Docs[^]


xpertzgurtej

спасибо за ваше предложение. Я пытался, но не смог найти желаемого результата.

OriginalGriff

Что ты пытался сделать? Что она дала тебе такого, чего ты не хотел?

xpertzgurtej

я пыталась выбрать имя пользователя,AttendanceType, мин(InOutDateTime) min_InDateTime, Макс(InOutDateTime) max_OutDateTime
от @группа ТБ на пользователя, литой(InOutDateTime как дата),AttendanceType
наличие AttendanceType in ('I','O')
Заказ по идентификатору пользователя, литой(InOutDateTime как дата). Это дает мне 6 строк вместо 3 строк

xpertzgurtej

Объявите таблицу @tbDate(Sno INT IDENTITY(1,1), AttendanceDate DATE, USerId INT)

Вставить @tbDate выбирать разные оттенки(InOutDateTime как дата),идентификатор пользователя от @ТБ

Объявить @tbDateCount ИНТ=(выбрать количество(*) из @tbDate), @идентификатор rowid ИНТ=1

Объявить @дата AttDate,@жидкость типа int,@MaxInOutTime типа datetime,@MinInOutTime типа datetime

Объявить @FinalResult стол(Кодсотрудника ИНТ, Интайм типа datetime, DateTime и OutTime)

WHILE @RowId<=@tbDateCount
НАЧАТЬ
Выберите @AttDate=AttendanceDate , @идентификатор=идентификатор пользователя с @tbDate где СНО=@идентификатор rowid

SELECT @MinInOutTime=(SELECT MIN(InOutDateTime) FROM @tb
Где литой(InOutDateTime как дата)=@AttDate и userId=@UID и функции isnull(AttendanceType,")= случай, когда AttendanceType не null тогда " я " еще " конец),
@MaxInOutTime=(выберите MAX(InOutDateTime) из @tb
Где литой(InOutDateTime как дата)=@AttDate и userId=@UID и функции isnull(AttendanceType,")= случай, когда AttendanceType не null тогда " о "другом" конце)

Вставить @FinalResult выберите @Уид @MinInOutTime,@MaxInOutTime
Набор @идентификатор rowid=@идентификатор rowid+1
КОНЕЦ

Выберите * из @FinalResult


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

xpertzgurtej

Кто-нибудь может помочь