mhd.sbt Ответов: 2

Как оптимизировать этот запрос без курсора?, Я не хочу использовать курсор, Спасите мою жизнь, пожалуйста ; (:(


DECLARE cr CURSOR FAST_FORWARD FOR
SELECT [CardNo],[Time] FROM 
@Data
ORDER BY [Time]
OPEN cr
FETCH NEXT FROM cr INTO @CardNo, @Time
WHILE (@@FETCH_STATUS = 0)
BEGIN
		SELECT  CASE WHEN details.[EffectiveDate] = currentDetails.[CurrentEffectiveDate] THEN 1 ELSE 0 END AS 
		IsCurrent,details.PersonnelBASeId, details.EffectiveDate, details.CardNo
		INTO ##tmp
		FROM           tblPersonnelDetails AS details LEFT OUTER JOIN
									 (SELECT        PersonnelBASeId, MAX(EffectiveDate) AS CurrentEffectiveDate
									   FROM            tblPersonnelDetails
									   WHERE        (ISNULL(Deleted, 0) = 0) AND (EffectiveDate <= @Time) 
									   GROUP BY PersonnelBASeId) AS currentDetails ON details.PersonnelBASeId = currentDetails.PersonnelBASeId
		WHERE        (ISNULL(details.Deleted, 0) = 0)  ORDER BY EffectiveDate DESC,PersonnelBaseId DESC
END
END
CLOSE cr
DEALLOCATE cr


Что я уже пробовал:

оптимизация запросов в tsql ,
я не хочу использовать курсор, он очень медленный

David_Wimbley

Без какой-либо схемы это не имеет большого смысла. Я смущен тем, почему вы используете курсор, когда все, что вы делаете, - это оператор select.

mhd.sbt

я хочу просто удалить этот курсор , в теле Курсора у меня есть только временная переменная, которую я не могу найти (например, с помощью Join).

David_Wimbley

Итак, если вы просто хотите удалить курсор, почему бы не взять все, что находится между операторами hte BEGIN и END вашего курсора? Похоже, ваша временная переменная не меняется?

mhd.sbt

хорошо, как я могу это сделать , в каждой итерации переменная времени меняется с помощью цикла Курсора ,
а можно иметь разное время, так, как изменить вышеописанный запрос без Курсора ,
есть идея, как изменить этот запрос?

2 Ответов

Рейтинг:
1

Wendelius

Не уверен, правильно ли я прочитал это утверждение, но мне кажется, что вы его не используете. @CardNo везде. Вы только используете @Time таким образом, оператор будет извлекать все строки из tblPersonnelDetails, на самом деле несколько раз, столько раз, сколько строк найдено для @Data в зависимости от EffectiveDate.

Поэтому, если вы хотите получить строки на основе столбца max of Time, возможно, просто

SELECT  CASE 
           WHEN details.[EffectiveDate] = currentDetails.[CurrentEffectiveDate] THEN 1
           ELSE 0 
        END AS IsCurrent,
        details.PersonnelBASeId, 
        details.EffectiveDate, 
        details.CardNo
INTO ##tmp
FROM tblPersonnelDetails AS details 
LEFT OUTER JOIN
(   SELECT PersonnelBASeId, 
           MAX(EffectiveDate) AS CurrentEffectiveDate
    FROM   tblPersonnelDetails
    WHERE   (ISNULL(Deleted, 0) = 0) 
    AND (EffectiveDate <= (SELECT MAX([Time]) FROM @Data)) 
    GROUP BY PersonnelBASeId) AS currentDetails 
    ON details.PersonnelBASeId = currentDetails.PersonnelBASeId
WHERE (ISNULL(details.Deleted, 0) = 0)  
ORDER BY EffectiveDate DESC,PersonnelBaseId DESC

Но, как уже было сказано, это немного забавно. Если вы намереваетесь получить только время для конкретного cardno, просто добавьте корреляцию во внутренний запрос.


mhd.sbt

Нет, ваше решение неверно, предположим, что @data содержит 200 строк с разным временем, а также игнорирует переменную @cardNo

Wendelius

Как уже было сказано, ваш исходный запрос, похоже, вообще не использует @cardno. Я не уверен, намеренно это или нет.

Не могли бы вы объяснить, каким должен быть результат? Тогда, возможно, будет проще изменить код.

mhd.sbt

наконец, я хочу, чтобы связанный персонал приходил в CardNO каждый раз(дата)

tblPersonnelDetails может содержать несколько строк с EffectiveDate и CardNo для одного персонала