SQL查询帮助

时间:2009-06-02 11:40:10

标签: sql sql-server-2000

使用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

CardeventdateCardeventtime - 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点)

7 个答案:

答案 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'

参数是:

  • '20090223' - 您24小时的开始日期(您的过滤器)
  • WHERE子句中的
  • 150000表示15:00:00的开始时间。更改它将为您提供不同的24小时范围。如果准确的时间应该转到另一个日期,您可能希望它为150001。
    • 删除过滤器(WHERE子句)将为您提供所有结果,如果取消注释“StartDate”列,您可以在以后进一步过滤

它的实现方式是通过组合你的日期和时间的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

注意事项:

  • 对于第二天00:00:00至03:00:00之间的人,CardEvenDateAdjusted不完全正确
  • 小于030000的MinTime意味着它实际上是第二天,所以事实上它并不是真正的MIN ......
  • 如果你的CardEventTime是sting(不是整数),那么你必须确保它有前导零(020000,而不是20000),否则MIN,MAX将不会正确排序,因此20000高于150000。

再说一遍:除非你重新提出一个好的问题,否则你找不到想要的答案。