2009-06-30 1 views
0

Я использую MS ACCESS 2003Group по, заказ на, подзапросы - Проблема производительности для получения предыдущего значения строки

ИМЯ ТАБЛИЦЫ -> tmp_cardevent

PERSONID CARDEVENTDATE CARDEVENTTIME 

5008  20090805  080000 
5008  20090805  140000 
5008  20090809  180000 
5008  20090809  220000 
3405  20090805  080000 
3405  20090805  180000 
3405  20090809  070000 
3405  20090809  230000 
3010  20080806  090000 
3010  20080806  230000 
3010  20080810  100000 
3010  20080810  160000 

Я хочу, чтобы отобразить время Сегодня и предыдущий дневное время для человека id Предыдущий день означает не вчера, предыдущий день для конкретного человека.

я сделать следующий запрос для получения предыдущего значения строки

select t1.Personid, 
    t1.cardeventdate, 
    t1.cardeventtime, 
    t2.Personid, 
    t2.cardeventdate, 
    t2.cardeventtime 
from tmp_cardevent t1 inner join tmp_cardevent t2 on t1.cardno = t2.cardno 
where t2.cardeventdate = (
    select max(cardeventdate) 
    from tmp_cardevent ds 
    where ds.cardeventdate < t1.cardeventdate 
     and ds.cardno = t1.cardno 
    ) 

Из выше запроса предыдущей строки отображения отлично

Ожидаемый выход

PERSONID CARDEVENTDATE  LastCARDEVENTDATE 

5008  20090809   20090805  
3405  20090809   20090805  
3010  20080810   20080806  

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

Так может ли кто-нибудь помочь мне получить лучшее решение для такой проблемы?

или любая другая помощь по запросу?

+0

Каков ожидаемый результат, учитывая предоставленные данные образца? – shahkalpesh

+0

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

+0

Я добавил свой ожидаемый результат, Да, я хочу получить всю текущую дату строки, дату предыдущей строки для персонифицированного – Gopal

ответ

1
SELECT 
    Seq = identity(int, 1, 1), 
    CardNo, 
    CardEventDate 
INTO #CardSeq 
FROM tmp_cardevent 
ORDER BY CardNo, CardEventDate 

SELECT 
    t1.Personid, 
    t1.cardeventdate, 
    t1.cardeventtime, 
    t2.Personid, 
    t2.cardeventdate, 
    t2.cardeventtime 
from 
    tmp_cardevent t1 
    inner join #CardSeq S1 ON t1.CardNo = S.CardNo 
    left join #CardSeq S2 ON t1.CardNo = t2.CardNo and t1.Seq - 1 = t2.Seq 
    left join tmp_cardevent t2 on t1.cardno = t2.cardno 

DROP TABLE #CardSeq 

Внесение указателя в таблицу темп на CardNo и/или Seq должно помочь. Создание таблицы temp с индексами перед ее заполнением, вероятно, лучше, чем добавление индексов после использования SELECT INTO. Экспериментируйте с кластеризованным индексом только по каждому столбцу, затем сгруппируйте по одному столбцу + некластерный на другом и наоборот, чтобы узнать, что дает лучшую производительность.

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

Необходимы левые соединения, иначе первое событие никогда не появится.

0

Вам нужно иметь индексы на ваших сгруппированных и упорядоченных столбцах.

например. создания индекса в столбце Last_Name в таблице Customer. CREATE INDEX IDX_CUSTOMER_LAST_NAME на КЛИЕНТА (Last_name)

Аналогично вы можете создать индексы на столбцах, используемых в вашей группе и положения порядка.

+0

Не очищено, вы можете помочь, как сделать? – Gopal

+0

Отредактировал свой ответ. Пожалуйста, проверьте. –