不使用游标分组

时间:2011-12-13 11:20:50

标签: sql sql-server sql-server-2008 tsql stored-procedures

考虑以下查询。 我为这个查询创建了一个游标。 我的问题是在光标中无法正常工作的组。但是当我执行查询时,它会按结果给出完美的分组。

当我使用FETCH NEXT和WHILE循环迭代游标时,它为同一个point_id提供了多个组。

你可以帮我解决这个问题吗? 提前谢谢..

select timestamp as 'TS',REPLACE(REPLACE(POINT_ID,'[','_'),']','_') AS POINT_ID,_VAL 
from TCF1_PULLCORD 
where timestamp between '11/01/2011 6:30:00 AM' and '12/01/2011 6:29:59 AM'
group by point_id,timestamp,_val


DECLARE MYCUR CURSOR 
FOR
    select timestamp as 'TS',REPLACE(REPLACE(POINT_ID,'[','_'),']','_') AS POINT_ID,_VAL 
    from TCF1_PULLCORD 
    where timestamp between '11/01/2011 6:30:00 AM' and '12/01/2011 6:29:59 AM'
    group by point_id,timestamp,_val

2 个答案:

答案 0 :(得分:2)

这是您的数据库说“请不要在我身上使用光标”的方式。 :d

开个玩意儿,但是说实话,你会发现迭代表变量比使用游标更好。

DECLARE @timestamps TABLE( 
    TS DATETIME,
    POINT_ID VARCHAR(100),
    _VAL VARCHAR(100)
    )
DECLARE @currTimeStamp DATETIME 

INSERT INTO @timestamps 
select timestamp as 'TS',REPLACE(REPLACE(POINT_ID,'[','_'),']','_') AS POINT_ID,_VAL 
from TCF1_PULLCORD 
where timestamp between '11/01/2011 6:30:00 AM' and '12/01/2011 6:29:59 AM'
group by point_id,timestamp,_val


WHILE (SELECT COUNT(TS) FROM @timestamps > 0)
BEGIN
    SELECT @currTimeStamp = MIN(TS) FROM @timestamps
    --Do work here
    ...

    --Delete the timestamp we just worked on
    DELETE FROM @timestamps WHERE TS = @currTimeStamp
END 

此外,除非您的SELECT正在执行我们在此处看不到的其他内容,否则GROUP BY应该是不必要的。如果你没有做任何聚合函数(例如SUM,MAX,MIN)并且你真的只是想获得独特的组合,那么SELECT DISTINCT是一种更有效的方法。

在这种情况下,您的选择将是:

select DISTINCT timestamp as 'TS',REPLACE(REPLACE(POINT_ID,'[','_'),']','_') AS POINT_ID,_VAL 
from TCF1_PULLCORD 
where timestamp between '11/01/2011 6:30:00 AM' and '12/01/2011 6:29:59 AM'

答案 1 :(得分:1)

不确定这是否对您有所帮助,但它至少更准确。

DECLARE MYCUR CURSOR 
FOR
    select  timestamp as 'TS'
            ,REPLACE(REPLACE(POINT_ID,'[','_'),']','_') AS POINT_ID
            ,_VAL 
    from    TCF1_PULLCORD 
    where   timestamp between '11/01/2011 6:30:00 AM' and '12/01/2011 6:29:59 AM'
    group by 
            REPLACE(REPLACE(POINT_ID,'[','_'),']','_')
            ,timestamp
            ,_val