使用SQL SERVER - 2000
表格结构
CARDEVENTDATE CARDEVENTTIME CARDNO
20090224 92007 485
20090224 92345 321
20090225 163932 168
20090225 164630 471
20090225 165027 488
20090225 165137 247
20090225 165147 519
20090225 165715 518
20090225 165749 331
20090303 162059 240
20090303 162723 518
20090303 155029 386
20090303 155707 441
20090303 162824 331
Cardeventdate
和Cardeventtime
- nvarchar数据类型
日期和时间是单独的列
我想在
之间获取数据昨天03:00:01 AM至今天03:00:00 AM 前天03:00:01 AM到昨天03:00:00 AM 所以...... ......
我尝试了下面提到的查询
Select Cardno, cardeventdate, min(cardeventtime), max(cardeventtime)
from table
where cardeventtime between 030001 to 030000
Select Cardno, Cardeventdate, Min(cardeventtime), max(cardeventtime)
from table
where Cardeventtime >030001 and Cardeventtime < 030000
结果中没有显示任何内容,因为今天的时间从早上03.00到凌晨03.01
Select Cardno, Cardeventdate, min (cardeventtime), max (cardeventtime)
from table
where cardeventtime < 030000 and cardeventtime > previous day time – query help
我正好需要昨天上午03.00.01到今天03.00.00数据,前天03.00.01上午03.00.00上午03.00.00数据.....................。所以
我需要sql查询以满足上述条件。任何人都可以帮助我吗?
(编辑:我需要从昨天早上到今天早上的日期,直到凌晨03点)
答案 0 :(得分:1)
以下是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
答案 1 :(得分:0)
查询中的日期格式似乎是特定于实现的。
正确的SQLServer2000,您希望使查询将日期用作日期 - 而不是数字。你真的应该有一个'datetime'类型的单个字段,而不是两个单独的字段。但是如果你无法控制它,那么你需要做一些日期时间的添加。我举一个例子。
尝试这样的事情:
SELECT * FROM table
WHERE
(DATEDIFF(dd, GetDate(), CARDEVENTDATE) = 1 AND CARDEVENTTIME > 030001 ) OR
(DATEDIFF(dd, GetDate(), CARDEVENTDATE) = 0 AND CARDEVENTTIME < 030000 )
答案 2 :(得分:0)
这是不正确的,因为条件总是为假:(你将日期存储为整数而不是日期时间,并且整数无法知道它应该在午夜环绕)
Select Cardno, Cardeventdate, Min(cardeventtime),
max(cardeventtime) from table where Cardeventtime >030001
and Cardeventtime < 030000
查询应该这样写:
Select Cardno, Cardeventdate, Min(cardeventtime),
max(cardeventtime) from table where (Cardeventtime between 030001 and 120000)
OR (cardeventtime between 000000 and 030000)
一旦将此因素纳入其他查询,您就应该能够找到解决方案。
编辑:对不起,在查询中表示OR而不是AND。
答案 3 :(得分:0)
select *
from someTable
where cardeventtime not between 30000 and 30001
order by cardeventdate, cardeventtime
答案 4 :(得分:0)
脚本是SQLServer2005,但使用#Temp表,您应该能够将其转换为可用的SQLServer2000脚本。
如果我理解正确,请按照 dd 03:00:00 - dd + 1对脚本分组记录 三点00分00秒
DECLARE @Table TABLE (
CARDEVENTDATE INTEGER
, CARDEVENTTIME INTEGER
, CARDNO INTEGER)
DECLARE @TableDateTime TABLE (
CARDEVENTDATETIME DATETIME
)
INSERT INTO @Table VALUES (20090224,92007,485)
INSERT INTO @Table VALUES (20090224,92345,321)
INSERT INTO @Table VALUES (20090225,163932,168)
INSERT INTO @Table VALUES (20090225,164630,471)
INSERT INTO @Table VALUES (20090225,165027,488)
INSERT INTO @Table VALUES (20090225,165137,247)
INSERT INTO @Table VALUES (20090225,165147,519)
INSERT INTO @Table VALUES (20090225,165715,518)
INSERT INTO @Table VALUES (20090225,165749,331)
INSERT INTO @Table VALUES (20090303,162059,240)
INSERT INTO @Table VALUES (20090303,162723,518)
INSERT INTO @Table VALUES (20090303,155029,386)
INSERT INTO @Table VALUES (20090303,155707,441)
INSERT INTO @Table VALUES (20090303,162824,331)
INSERT INTO @TableDateTime
SELECT
[DATETIME-3] =
DATEADD(MONTH, ((CARDEVENTDATE/10000-1900)*12)+(CARDEVENTDATE/100)%100-1, CARDEVENTDATE%100-1)
+ DATEADD(SS, (((CARDEVENTTIME/10000)-3)*3600)+(((CARDEVENTTIME/100)%100)*60)+CARDEVENTTIME%100, 0)
FROM @Table
SELECT CAST(CAST(tdt1.CARDEVENTDATETIME-1 AS INTEGER) AS DATETIME), COUNT(*)
FROM @TableDateTime tdt1
GROUP BY CAST(tdt1.CARDEVENTDATETIME-1 AS INTEGER)
/*
What do all the casts, div's and mods mean
*/
SELECT
/* Split */
[YEAR] = CARDEVENTDATE / 10000
, [MONTH] = (CARDEVENTDATE / 100) % 100
, [DAY] = CARDEVENTDATE % 100
, [HOUR] = CARDEVENTTIME / 10000
, [MINUTE] = (CARDEVENTTIME / 100) % 100
, [SECOND] = CARDEVENTTIME % 100
/* Date & Time */
, [DATE] = DATEADD(MONTH, ((CARDEVENTDATE/10000-1900)*12)+(CARDEVENTDATE/100)%100-1, CARDEVENTDATE%100-1)
, [TIME] = DATEADD(SS, (CARDEVENTTIME/10000*3600)+(((CARDEVENTTIME/100)%100)*60)+CARDEVENTTIME%100, 0)
/* DateTime */
, [DATETIME] =
DATEADD(MONTH, ((CARDEVENTDATE/10000-1900)*12)+(CARDEVENTDATE/100)%100-1, CARDEVENTDATE%100-1)
+ DATEADD(SS, (CARDEVENTTIME/10000*3600)+(((CARDEVENTTIME/100)%100)*60)+CARDEVENTTIME%100, 0)
, [DATETIME-3] =
DATEADD(MONTH, ((CARDEVENTDATE/10000-1900)*12)+(CARDEVENTDATE/100)%100-1, CARDEVENTDATE%100-1)
+ DATEADD(SS, (((CARDEVENTTIME/10000)-3)*3600)+(((CARDEVENTTIME/100)%100)*60)+CARDEVENTTIME%100, 0)
FROM @Table
ORDER BY [DATETIME]
答案 5 :(得分:0)
第1步
首先将包含日期和时间的两列放在carddate
类型的一列(即datetime
)中。
第2步
如果你想根据白天的某些分段时间进行分组,可以做类似的事情(例如凌晨3点的分段时间):
select min(carddate) as Minimum, max(carddate) as Maximum
from sampleTable
group by
year(dateadd(hour, -3, carddate)),
month(dateadd(hour, -3, carddate)),
day(dateadd(hour, -3, carddate))
但是你无法在群组中获得像这样简单的卡号。您必须使用用户功能来实现这种功能
答案 6 :(得分:0)
仅使用查询的解决方案:
SELECT CardEventDate, CardEventTime, CardNo
,(1000000*CAST(CardEventDate AS BIGINT) + CAST(CardEventTime AS BIGINT)) AS CardEventDateTimeINT
,((1000000*CAST(CardEventDate AS BIGINT) + CAST(CardEventTime AS BIGINT))-150000)/1000000 AS StartDate
FROM "table"
WHERE ((1000000*CAST(CardEventDate AS BIGINT) + CAST(CardEventTime AS BIGINT))-150000)/1000000 = '20090223'
参数是:
它的实现方式是通过组合你的日期和时间的DATETIME,但不使用DATETIME数据类型,而只使用BIGINT,因此20090224092007的值将是20090224的日期和092007的时间。最重要的是是它仍然是可排序的,只需使用INTEGER部门就可以轻松切断/转移购买。这就是我买的减去150000(时间15:00:00)。
结果(在上面的查询中使用过滤器)是:
CardEventDate CardEventTime CardNo CardEventDateTimeINT StartDate
------------- ------------- ------ -------------------- --------------------
20090224 92007 485 20090224092007 20090223
20090224 92345 321 20090224092345 20090223
下面没有任何过滤器的结果,以便您可以稍后按StartDate过滤:
CardEventDate CardEventTime CardNo CardEventDateTimeINT StartDate
------------- ------------- ------ -------------------- --------------------
20090224 92007 485 20090224092007 20090223
20090224 92345 321 20090224092345 20090223
20090225 163932 168 20090225163932 20090225
20090225 164630 471 20090225164630 20090225
20090225 165027 488 20090225165027 20090225
20090225 165137 247 20090225165137 20090225
20090225 165147 519 20090225165147 20090225
20090225 165715 518 20090225165715 20090225
20090225 165749 331 20090225165749 20090225
20090303 162059 240 20090303162059 20090303
20090303 162723 518 20090303162723 20090303
20090303 155029 386 20090303155029 20090303
20090303 155707 441 20090303155707 20090303
20090303 162824 331 20090303162824 20090303
这是GROUP BY,MIN(..)和MAX(..)的版本:
SELECT CardNo,
((1000000*CAST(CardEventDate AS BIGINT) + CAST(CardEventTime AS BIGINT))-30000)/1000000 AS CardEvenDateAdjusted,
MIN(CardEventTime) AS MinTime,
MAX(CardEventTime) AS MaxTime
--,COUNT(*) AS NUM
FROM "table"
GROUP BY CardNo, ((1000000*CAST(CardEventDate AS BIGINT) + CAST(CardEventTime AS BIGINT))-30000)/1000000
注意事项:
再说一遍:除非你重新提出一个好的问题,否则你找不到想要的答案。