2017-10-23 9 views
0

SQL Server에서 내 테이블에 문제가 있습니다. 언젠가 삽입하는 동안 보통 값 (20-50-80)이 1000000만큼 바뀌 었습니다. 정말 희귀하지만 평균을 확보하려면 새로운 해결책을 찾기 전에 수정해야합니다.SQL Server의 커서 : 루프/조건을 사용하여 값을 찾아서 바꾸기

1000000을 초과하는 값을 취하여 그 값의 평균으로 바꾸고 싶습니다.

This picture show the problem.

나는 SQL의 커서 찾고 있어요.

여기 내 코드 예입니다. 결과에 대한 일부 문제.

CREATE PROCEDURE [dbo].[Avg_Kwh_TagValuesArchive]  
AS 

BEGIN 

DECLARE @tagId INT 
DECLARE @localTime DATE 
DECLARE @tagValue FLOAT 
DECLARE @limit FLOAT 
DECLARE @temp FLOAT 
DECLARE @tagValueBefore FLOAT 
DECLARE @tagValueAfter FLOAT 
SET @limit = 999999.9 

DECLARE Cursor_FalseValues CURSOR 
FOR 
    SELECT TagID, LocalTime, TagValue 
    FROM TagValuesArchive 
    ORDER BY LocalTime DESC 

OPEN Cursor_FalseValues 

FETCH Cursor_FalseValues 
INTO @tagId, @localTime, @tagValue 

WHILE(@@FETCH_STATUS = 0) 
BEGIN 

      IF (@tagValue>[email protected]) 
      BEGIN 

       SET @tagValueBefore = 
       (
        SELECT TOP 1 TagValue 
        FROM TagValuesArchive 
        WHERE LocalTime < @localTime 
        AND TagID = @tagID 
        AND TagValue IS NOT NULL 
        ORDER BY LocalTime DESC 
       ) 

       SET @tagValueAfter = 
       (
        SELECT TOP 1 TagValue 
        FROM TagValuesArchive 
        WHERE LocalTime > @localTime 
        AND TagID = @tagID 
        AND TagValue IS NOT NULL 
        ORDER BY LocalTime DESC 
       ) 

       UPDATE dbo.TagValuesArchive 
       SET TagValue= ((SUM(@tagValueBefore + @tagValueAfter))/2) 
       FROM dbo.TagValuesArchive 
       WHERE LocalTime = @localTime 
       AND TagID = @tagID 

       FETCH NEXT FROM Cursor_FalseValues 
       INTO @tagId, @localTime, @tagValue 

      END 
     ELSE 
      BEGIN 
       -- Fetch of the Cursos increment the line 
       FETCH NEXT FROM Cursor_FalseValues 
       INTO @tagId, @localTime, @tagValue 
      END 
    -- Fetch of the Cursos increment the line 
    --FETCH NEXT FROM Cursor_FalseValues 
    --INTO @tagId, @localTime, @tagValue 
END 

CLOSE Cursor_FalseValues 
DEALLOCATE Cursor_FalseValues 
END 

내 문제는 Cursor를 사용하는 좋은 예라고 생각하지만 내 머리 속에는 명확하지 않습니다. 잘못된 값과 그 값을 가져올 수 있습니다. 그러나 데이터베이스의 업데이트가 작동하지 않습니다.

커서 문제인지 또는 업데이트인지 알 수 없습니다. 어쩌면 코드 구문 문제 일 수 있습니다.

모든 정보 주셔서 감사합니다.

답변

0

당신은 이런 식으로 뭔가를 시도 할 수 있습니다 :

DECLARE @t TABLE (
    id int, 
    val float 
) 


INSERT INTO @t (id, val) 
VALUES 
(1,.5), 
(2,.7), 
(3,.3), 
(4,.74), 
(5,.2341234), 
(6,10000000), 
(7,.9), 
(8,.8), 
(9,.87123), 
(10,100000000), 
(11,.99) 
SELECT * FROM @t 

DECLARE @limit FLOAT = 1000000; 

;WITH OutOfOBoundsValues AS (
    SELECT id FROM @t WHERE val >= @limit 
), Neighbourvalues AS (
    SELECT O.id, (t1.val+t2.val)/2 newval FROM OutOfOBoundsValues O 
    JOIN @t t1 ON t1.id = O.id-1 
    JOIN @t t2 ON t2.id = O.id+1 

) 
UPDATE @t 
SET val = N.newval 
FROM @t t 
JOIN Neighbourvalues N ON t.id = N.Id 


SELECT * FROM @t 

여기에서 발생하는 것은 우리가 같이 한계 이상으로 같은 데이터를 선택한다는 것입니다.

그러면 인접 값을 구하여 평균값을 계산합니다.

마지막으로 경계 값을 평균값으로 업데이트합니다.

커서보다 훨씬 빠릅니다.

+0

정보를 주셔서 감사합니다. 실제로이 예제에서는 조인이 훨씬 빠릅니다. – Zebiphire