SQL查询特定日期的顶部和底部值

时间:2009-06-10 07:43:37

标签: sql-server sql-server-2000

SQL Server 2000

我的表:

CARDNO  CARDEVENTDATE   CARDEVENTTIME
121 20090610    025050
 121    20090611    040000
121 20090611    050000
121 20090611    020000
122 20090611    030001
122 20090611    030000
123 20090611    080000
123 20090611    100000
123 20090611    132449
123 20090611    025959
124 20090610    030000
124 20090612    030001
125 20090611    030002
125 20090612    040000

Cardno是独立桌子 Cardeventdate,cardeventtime是单独的表

从上表中我想获得特定cardeventdate和Cardno的最佳时间和下限时间

对于121,20090611,Top Time是040000,Bottom Time是020000 对于123,20090611,Top Time是080000,Bottom Time是025959 ... 像我这样需要。

我使用Min(时间)和Max(时间),但它显示为这样。

对于CardNo - 121 Cardeventdate - 20090611 最短时间 - 020000 最长时间 - 040000

我不想得到min和Max,我只需要特定Date和Cardno的top和Bottom(或)First和Last time值。

我使用了这个查询

SELECT     RowNumber = IDENTITY (int, 1, 1), CARDNO, CARDEVENTDATE, CARDEVENTTIME INTO #Table1 FROM T_CARDEVENT SELECT     t1.CARDNO, t1.CARDEVENTDATE, t1.CARDEVENTTIME  FROM #Table t1 INNER JOIN (SELECT     RowNumber = MIN(RowNumber), CARDEVENTDATE, CARDNO  FROM  #Table1 t  WHERE      (cardeventdate > 20090601) GROUP BY cardno, cardeventdate  UNION ALL  SELECT     MAX(RowNumber), CARDEVENTDATE, CARDNO FROM #Table1 t WHERE     (cardeventdate > 20090601) GROUP BY cardno, cardeventdate) t2 ON t2.rownumber = t1.rownumber

输出:

ROWNUMBER   CARDNO  CARDEVENTDATE   CARDEVENTTIME
335 0121               20090611     040000
1099    0121               20090611     050000
1100    0121               20090611     025050
336 0121               20090612     020000
337 0122               20090611     030001
338 0122               20090612     030000
339 0123               20090611     080000
1101    0123               20090611     100000
1102    0123               20090611     132449
340 0123               20090612     025959
341 0124               20090611     030000
342 0124               20090612     030001
343 0125               20090611     030002
344 0125               20090612     040000

所以这里为所有列创建了行号,从中我可以获取特定日期的第一次和最后一次。

期待输出

CARDNO  CARDEVENTDATE   CARDEVENTTIME   Expecting
0121    20090611    040000  Top Value
0121    20090611    020000  No Need
0121    20090611    025050  Bottom Value

.........等等

需要查询帮助。

5 个答案:

答案 0 :(得分:5)

好吧,除非您有一些额外的字段来建立订单,否则这是不确定的。鉴于23-04-2009的三个值 - APPLE是第一个,ROSE是最后一个?如果所有三个条目的ID和DATE相同,则没有定义的顺序来过滤掉“GRAPHE”......

马克

更新:我稍微扩展了Lieven的想法,并在我的设置中使用了这个:

DECLARE @TempTable TABLE (RowNumber INT IDENTITY(1,1), 
                          DayNumber INT, 
                          ID VARCHAR(3), DateField DATETIME, Value VARCHAR(32))

INSERT INTO @TempTable(DayNumber, id, datefield, value)
    SELECT DATEPART(DAYOFYEAR, DateField), ID, DateField, Value
    FROM @Table

SELECT * 
FROM @TempTable t
INNER JOIN 
   (SELECT RowNumber = MIN(RowNumber), DayNumber, ID
    FROM @TempTable t
    GROUP BY DayNumber, t.ID
    UNION ALL 
    SELECT MAX(RowNumber), DayNumber, ID
    FROM @TempTable t
    GROUP BY DayNumber, t.ID) t2 
  ON t2.RowNumber = t.RowNumber
GO

我基本上创建了一个带有附加信息的临时表 - 一个用于创建一些订单的人工“RowNumber”,以及用于获取按日期分组的日期的“DayNumber”(没有时间)。

似乎对我有用 - 它对你有用吗?

答案 1 :(得分:1)

Jash,如果您执行此脚本,它会为您提供您期望的结果吗?

CREATE TABLE #T_Cardevent (CARDNO VARCHAR(3), CARDEVENTDATE VARCHAR(8), CARDEVENTTIME VARCHAR(8))

INSERT INTO #T_Cardevent VALUES ('121', '20090610', '025050')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '040000')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '050000')
INSERT INTO #T_Cardevent VALUES ('121', '20090611', '020000')
INSERT INTO #T_Cardevent VALUES ('122', '20090611', '030001')
INSERT INTO #T_Cardevent VALUES ('122', '20090611', '030000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '080000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '100000')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '132449')
INSERT INTO #T_Cardevent VALUES ('123', '20090611', '025959')
INSERT INTO #T_Cardevent VALUES ('124', '20090610', '030000')
INSERT INTO #T_Cardevent VALUES ('124', '20090612', '030001')
INSERT INTO #T_Cardevent VALUES ('125', '20090611', '030002')
INSERT INTO #T_Cardevent VALUES ('125', '20090612', '040000')

SELECT     
  RowNumber = IDENTITY (int, 1, 1)
  , CARDNO
  , CARDEVENTDATE
  , CARDEVENTTIME 
INTO #Table
FROM #T_CARDEVENT 

SELECT t1.CARDNO, t1.CARDEVENTDATE, t1.CARDEVENTTIME  
FROM #Table t1 
     INNER JOIN (
        SELECT RowNumber = MIN(RowNumber), CARDEVENTDATE, CARDNO 
        FROM #Table t  
        GROUP BY cardno, cardeventdate  
        UNION ALL SELECT MAX(RowNumber), CARDEVENTDATE, CARDNO 
        FROM #Table t 
        GROUP BY cardno, cardeventdate) t2 ON t2.rownumber = t1.rownumber
ORDER BY 1, 2, 3

DROP TABLE #Table
DROP TABLE #T_Cardevent

答案 2 :(得分:0)

我没有尝试过,但也许这样的事情可能会这样做:

SELECT TOP(1) FROM Table
WHERE Date='Some-date'
AND Id=Some-Id
ORDER BY Date ASC
UNION
SELECT TOP(1) FROM Table
WHERE Date='Some-date'
AND Id=Some-Id
ORDER BY Date Desc

答案 3 :(得分:0)

作弊你可以添加一个自动编号场 AUtoID ID日期值 1 001 23:04:2009 APPLE 2 001 23:04:2009 GRAPHE 3 001 23:04:2009玫瑰 4 001 24:04:2009 BERRY 5 001 24:04:2009 TIFFANY 6 001 24:04:2009 ORGANE 7 001 24:04:2009 SILVER

然后你可以对它做最小和最大

我通常使用insert进入一个用ID定义的临时表,从技术上来说,插入顺序不是garenteed进入。

答案 4 :(得分:0)

以下是使用内联视图的解决方案:

with 
tempFirst as (
    select id, date, value, 
     row_number() over (partition by id, date order by date asc) as rownum1
    from table1
),
tempLast as ( 
    select *, 
     row_number() over (partition by id, date order by rownum1 desc) as rownum2 
    from tempFirst
)
select id, date, value from tempFirst where rownum1 = 1
union
select id, date, value from tempLast where rownum2 = 1

我测试了输出,即:

ID  DATE       VALUE
001 2009-04-23 APPLE
001 2009-04-23 ROSE
001 2009-04-24 BERRY
001 2009-04-24 SILVER