Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Помогите с запросом [D7, MSSQL]


unicode ©   (2004-04-16 08:59:00) 

SQL SERVER
21601 - это номер, Дальше идет дата, 1 и 2 это вход и выход
как видно из примера то даный номер производит вход и выход
т.е. 1 - это вход, 2 - это выход
но есть момент когда Вход не произошелно произошел Выход
(см. пример)
21601 2003-01-09 12:46:37 1
21601 2003-01-09 16:50:00 2
21601 2003-01-10 12:46:53 1
21601 2003-01-10 16:50:00 2
21601 2003-01-11 12:40:05 1
21601 2003-01-11 17:50:10 2
21601 2003-01-12 12:45:00 1
21601 2003-01-12 18:40:00 2
21601 2003-01-13 18:00:00 1 - Вход
21601 2003-01-13 23:00:00 2 - Выход
21601 2003-01-14 23:28:48 2- Выход
21601 2003-01-15 19:04:36 2- Выход

отсюда видно что на выделенные даты не было входа но был выход..
Задача такая как получить эти данные вот в таком виде
Причем тоже самое можеть быть и с выходом то есть Вход будет а выхода нет

Номер | Вход |Дата | Выход |Дата
Номер | Вход |Дата | Выход |Дата
Номер | NULL |NULL | Выход |Дата
Номер | NULL |NULL | Выход |Дата
Номер | Вход |Дата | NULL  |NULL

то есть понятно что исходя из верхних данных получаеться что вместо двух входов которых небыло должен быть NULL

Кто-нибудь может помочь разобраться в этом? Да и записей в таблице больше 150000 .. и принаписании запроса мне кажеться лучше вообще не ссылаться на даты а пользоваться 1 и 2..


Johnmen   (2004-04-16 10:13:00) [1]

>unicode ©

Ещё замечу, что построение корректного запроса интересно лишь как разминка для мозгов и тренировка.
А практически стоит просто написать ХП.


unicode   (2004-04-16 09:58:00) [2]

>> Johnmen
а что если использовать куркос для перебора записей и сверять предидущую со следуещей типа если 1 то отьрасывать слево а если после него идет 2 но его кинуть к 1 в правую часть если повторяються числа 1 то обе в лево а справа НУЛ нет?


ЮЮ   (2004-04-16 09:56:00) [3]

SELECT *
FROM
 (Select * from Table Where z=1) Enters
 FULL JOIN (Select * from Table Where z=2) Exits
ON
 Enters.Id = Exits.EnterID

где EnterID - недастоющее поле связи записи о выходе с записью о входе(может быть NULL, но тогда пусть охрана выясняет, как он пробрался незамеченным). Добавь его. В процедуре заполни его один раз. В программе добавления записей о выходе добавь его заполнение. И будет тебе счастье :-)


Johnmen   (2004-04-16 09:55:00) [4]

>unicode ©  

Ясно, что я привел не точный ответ, а указал основные моменты:
1. Поскольку записи "разворачиваем" в горизонталь, то соединение табл.себя с собой.
2. Поскольку NULL справа и слева, то FULL JOIN.
3. Чтобы выделить принадлежность ухода приходу, MIN.

Вобщем надо немного подумать и всё получится...
:)


Anatoly Podgoretsky   (2004-04-16 09:55:00) [5]

Нафига обрабатывать данные за несколько лет?
А за месяц не будет 150000


tERRORist   (2004-04-16 09:50:00) [6]

Вот именно от этого и дохренища записей...


tERRORist   (2004-04-16 09:49:00) [7]

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


unicode   (2004-04-16 09:48:00) [8]

>> Johnmen работает но не совсем правильно сейчас пример кину что сделал запрос вот данные на одну карту

27420 2004-03-01 08:59:01.000 1
27420 2004-03-02 09:02:31.000 1
27420 2004-03-02 11:33:10.000 2
27420 2004-03-02 15:32:31.000 2
27420 2004-03-03 18:09:58.000 2
27420 2004-03-04 09:00:51.000 1
27420 2004-03-05 09:07:23.000 1
27420 2004-03-05 14:12:06.000 2
27420 2004-03-09 09:03:34.000 1
27420 2004-03-10 15:04:33.000 2
27420 2004-03-11 09:06:59.000 1
27420 2004-03-12 09:05:01.000 1
27420 2004-03-15 09:04:33.000 1
27420 2004-03-16 09:12:51.000 1
27420 2004-03-17 09:14:28.000 1
27420 2004-03-17 13:42:11.000 2
27420 2004-03-18 13:56:17.000 2
27420 2004-03-19 09:09:52.000 1
27420 2004-03-19 13:18:21.000 2
27420 2004-03-23 09:14:04.000 1
27420 2004-03-23 13:48:50.000 2
27420 2004-03-24 08:55:51.000 1
27420 2004-03-24 14:06:47.000 2
27420 2004-03-25 08:59:01.000 1
27420 2004-03-26 09:01:19.000 1
27420 2004-03-29 11:30:16.000 1
27420 2004-03-30 09:07:11.000 1
а вот результат твое запроса

27420 1 2004-03-01 08:59:01.000 2 2004-03-02 11:33:10.000
27420 1 2004-03-04 09:00:51.000 2 2004-03-05 14:12:06.000
27420 1 2004-03-09 09:03:34.000 2 2004-03-10 15:04:33.000
27420 1 2004-03-11 09:06:59.000 2 2004-03-17 13:42:11.000 --
27420 1 2004-03-12 09:05:01.000 2 2004-03-17 13:42:11.000 --
27420 1 2004-03-15 09:04:33.000 2 2004-03-17 13:42:11.000 --
27420 1 2004-03-16 09:12:51.000 2 2004-03-17 13:42:11.000

-- обшибочные данные


A_N_D   (2004-04-16 09:42:00) [9]

select t1.[Номер], t1.[Вход], t1.[Дата] as d1, t2.[Выход], t2.[Дата] as d2, srt=case When t1.[Дата] is null then t2.[Дата] else t1.[Дата] end
from Table t1
inner join table t2 on t2.номер=t1.номер and t2.Вход=2 and t1.Вход=1
order by srt


unicode   (2004-04-16 09:36:00) [10]

>> Johnmen

сейчас попробую...


tERRORist   (2004-04-16 09:35:00) [11]

Да с такой организацией данных получить результат будет геморрно.
Тут всяко не обойтись без функции которая бы искала запись предыдущего типа(вход/выход), которая была всавлена до текущей и между ними нет записей текущего типа.


unicode   (2004-04-16 09:34:00) [12]

таблица одна... даты разные, неужели решения этой проблеме??


Johnmen   (2004-04-16 09:33:00) [13]

Примерно так:


SELECT T1.ID, T1.Z, T2.Z, T1.DT, MIN(T2.DT)
FROM Table T1
FULL JOIN Table T2 ON (T2.ID=T1.ID) AND
                  (T1.Z=1) AND (T2.Z=2) AND
                  (T1.DT<=T2.DT)
GROUP BY T1.ID, T1.Z, T2.Z, T1.DT


Z = 1-вход, 2-выход;
DT - датавремя


ЮЮ   (2004-04-16 09:30:00) [14]

Хоть убейте, не понимаю, почему, когда явно напрашивается ЯВНАЯ связь между записями, не сделать её на уровне ДАННЫХ и не получать затем нужные пары "на лету", а не продолжать ежедневно насиловать сервер?


unicode   (2004-04-16 09:27:00) [15]

неа не получилось прошло 30 секунд а запрос еще идет, я остановил, в таблице сейчас примерно 32000 записей а запрос который я остановил уже вернул 900000 записей ... не работает


unicode   (2004-04-16 09:23:00) [16]

сейчас попробуюю далеко не уходи..


A_N_D   (2004-04-16 09:20:00) [17]

select t1.[Номер], t2.[Вход], t2.[Дата] as d1, t3.[Выход], t3.[Дата] as d2
from Table t1
left outer join table t2 on t2.номер=t1.номер and t2.Вход=1
left outer join table t3 on t3.номер=t1.номер and t3.Вход=2


Наверх

Титульная страница Поиск, карта сайта Написать письмо