Ниже приведен тест на SQL Server 2005 Express. Если SQL Server 2000 не имеет общих табличных выражений (CTE), вместо этого можно использовать представление для создания того же, что и cteTbl. И я надеюсь, что SQL Server 2000 поддерживает CASE-WHEN-END.
Идея, которую я использую в этом, заключается в том, чтобы увеличить количество часов в день с 24 до 27 часов (+3), но только в том случае, если [CardEventTime] меньше или равно 03:00:00 (24 часа). Я добавляю 24 часа. и [CardEventDate] вычесть 1d.
CREATE TABLE tbl (
CardEventDate INTEGER
,CardEventTime INTEGER
,CardNo INTEGER
)
INSERT INTO tbl VALUES (20090224,92007,485)
INSERT INTO tbl VALUES (20090224,92345,321)
INSERT INTO tbl VALUES (20090225,163932,168)
INSERT INTO tbl VALUES (20090225,164630,471)
INSERT INTO tbl VALUES (20090225,165027,488)
INSERT INTO tbl VALUES (20090225,165137,247)
INSERT INTO tbl VALUES (20090225,165147,519)
INSERT INTO tbl VALUES (20090225,165715,518)
INSERT INTO tbl VALUES (20090225,165749,331)
INSERT INTO tbl VALUES (20090303,162059,240)
INSERT INTO tbl VALUES (20090303,162723,518)
INSERT INTO tbl VALUES (20090303,155029,386)
INSERT INTO tbl VALUES (20090303,155707,441)
INSERT INTO tbl VALUES (20090303,162824,331)
-- Some boundary test values, for only one cardno.
INSERT INTO tbl VALUES (20090330,235959,331)
INSERT INTO tbl VALUES (20090331,000000,331)
INSERT INTO tbl VALUES (20090331,025959,331)
INSERT INTO tbl VALUES (20090331,030000,331)
INSERT INTO tbl VALUES (20090331,030001,331)
INSERT INTO tbl VALUES (20090331,235959,331)
INSERT INTO tbl VALUES (20090401,000000,331)
INSERT INTO tbl VALUES (20090401,025959,331)
INSERT INTO tbl VALUES (20090401,030000,331)
INSERT INTO tbl VALUES (20090401,030001,331)
go
WITH
cteTbl AS (
SELECT
CardEventDate,
CardEventTime,
CardNo,
CASE
WHEN CardEventTime <= 30000 THEN dateadd(dd, -1, cast(CardEventDate AS VARCHAR))
WHEN CardEventTime > 30000 THEN cast(cast(CardEventDate AS VARCHAR) AS DATETIME)
END AS ShiftedCardEventDate,
CASE
WHEN CardEventTime <= 30000 THEN CardEventTime+240000
WHEN CardEventTime > 30000 THEN CardEventTime
END AS ShiftedCardEventTime
FROM tbl
)
SELECT
CardNo,
ShiftedCardEventDate,
--min(shiftedCardEventTime) as [MinCardEventTime],
--max(shiftedCardEventTime) as [MaxCardEventTime],
right('000000'+cast((min(shiftedCardEventTime) % 240000) AS VARCHAR), 6) AS [NormalizedMinTime],
right('000000'+cast((max(shiftedCardEventTime) % 240000) AS VARCHAR), 6) AS [NormalizedMaxTime]
FROM cteTbl
GROUP BY
CardNo,
ShiftedCardEventDate