|
19 Кб. |
|
| Есть таблица (во вложении).
вначале, что за столбцы.
код - обычный счетчик
сотрудник - сюда записывается код из таблицы сотрудники
Номер - сюда записывается код из таблицы телефонов.
Действие - принимает два значения (выдача/сдача) (выдается телефон или сдается определенным сотрудником)
Дата заявления - (дата акта приема или сдачи телефона)
kod - сюда записывается код из этой же таблицы. по правилу: код - соответствует записиы выдаваемому/сдаваемому сотруднику определеенный телефон, что бы связать две записи (выдачи и сдачи телефона одинм сотрудником).
и получается, что поле kod будет пустым если телефон выдан, но еще не сдан.
телефон дпусти с кодом 67 заводится в базу попадает в резерв. т.е получается строчка
для резерва тоже есть определенный код пустьбудет 1.
код | kod | сотрудник | номер | действие | дата заявления
1 |____| 1 | 67 | выдача | 02/02/2011
далее есть необходимость выдать телефон новому сотруднику (пусть будет код = 3)
но для того чтобы выдать телефон сотруднику нужно его вывести из резерва. дата заявления вывода из резерва будет равна дате выдачи сотруднику. т.е. получается еще две строчки, а так же в первую строчку записываем в поле kod код строки вывода из резерва, а в строку кода вывода из резерва записываем код ввода в резерв. т.е получаем в конечном этоге 3 записи.
код | kod | сотрудник | номер | действие | дата заявления
1 | 2 | 1 | 67 | выдача | 02/02/2011
2 | 1 | 1 | 67 | сдача | 01/03/2011
3 | ____| 3 | 67 | выдача | 01/03/2011
теперь нужно сдать телефон сотрудником обратно в резерв. по подобию ситуации описанной выше получаем следующее
код | kod | сотрудник | номер | действие | дата заявления
1 | 2 | 1 | 67 | выдача | 02/02/2011
2 | 1 | 1 | 67 | сдача | 01/03/2011
3 | 4 | 3 | 67 | выдача | 01/03/2011
4 | 3 | 3 | 67 | сдача | 05/06/2011
5 |____| 1 | 67 | выдача | 05/06/2011
ну и т.д. все это работает все это заносится и вроде быпроблем нет. информация сохраняется
теперь втала задача сделать запрос выбрать всех сотрудников, кто пользовался телефоном в определенный меся и год.
пока решил это с помощью нескольких запросов.
1. первый запрос я делаю из этой таблицы всех записей соответсвующие условию [дата заявления] <= последнее число интересующего месяца определеннго года и действие=выдача
2. второй запрос я делаю из этой же таблицы всех записей [дата заявления] < первое число интересующего месяца определеннго года и действие=сдача
3. третий запрос: выбираю все поля из первого запроса и только тех записей из вторго запроса где код первого запроса совпадает с kod второго запрса и ставлю фильтр kod второго запроса в результирующей тбалице равен null и получаю список сотрудников, котрые пользовались телефонами в определенный месяц.
+ делаю еще несколлько запросов, что бы вывести один столбец выдан, второй столбец сдан
может можно как то проще сделать запрос?
P.S. прошу прощения за такой большой текст и сумбур. если уйдет сообщение в off тоже пойму | |
|
| |
|
|
|
| Пока только вопрос.
Зачем так сложно?
почему не достаточно 1-й записи определяющей смену владельца?
Либо владелец человек - либо владелец "резерв"
дата записи определяет дату начала пользования телефоном или дату передачи в резерв и соответственно дату сдачи
Добавлено.
У меня таких таблиц 2
одна определяет историю выдачи номера
вторая историю лимитов оплачиваемых фирмой по данному номеру (т.е. сколько фирма компенсирует денег)
Выглядят так.
таблица tblHistoryUsers
HistoryID - счетчик
NumTel - номер телефона
UserID - код пользователя
dtBegin - дата выдачи пользователю
Еще добавлено.
Есть также таблица с телефонами tblTelephones
запрос выводящий информацию по номеру и код пользователя который сейчас им пользуется выглядит так
SELECT dbo.tblTelephones.*,
(SELECT TOP 1 tblHistoryUsers.UserID
FROM tblHistoryUsers
WHERE tblHistoryUsers.NumTel = tblTelephones.NumTel
ORDER BY dtbegin DESC) AS CurrentUserID
FROM dbo.tblTelephones
|
| |
|
| |
|
|
|
| ну и наконец получение кода пользователя по телефону на нужную дату
SELECT TOP (1) UserID
FROM dbo.tblHistoryUsers
WHERE (dtBegin <= [нужная дата]) AND (NumTel = [Нужный Номер])
ORDER BY dtBegin DESC) AS CurrentUserID
|
если по всем номерам, то так
SELECT dbo.tblTelephones.*,
(SELECT TOP 1 tblHistoryUsers.UserID
FROM tblHistoryUsers
WHERE (dtBegin <= [нужная дата]) AND tblHistoryUsers.NumTel = tblTelephones.NumTel
ORDER BY dtbegin DESC) AS CurrentUserID
FROM dbo.tblTelephones
|
добавлено.
А кто когда каким номером пользовался видно прямо в таблице
tblHistoryUsers | |
|
| |
|
|
|
| спасибо за подсказку, что то я как то не подумал про избыточность данных. хотя может я это делал с какой то целью, такой принцип записи и хранение данных, только не могу пока вспомнить.
кстати попутно вопрос, а зачем в запросе где выбирается только одна запись, по конкретному условию, ставить ( ТОР ( 1))? это как то влияет на быстродействие? | |
|
| |
|
|
|
| Записей соответствующих условию в таблице историй может быть и несколько. | |
|
| |
|
|
|
| если я правильно понимаю, то допустим мне нужно вывести всех пользователей в июне.
то при таком запросе он мне покажет всех пользователей определенного номера выданных ранее июня и в июне т.е.
пупкин номер 11111 10.04.2011
тюлпаныч номер 11111 10.05.2011
ромашкин номер 11111 25.06.2011
а вот как отбросить в данном случае первую запись, так как он в июне не пользовался. | |
|
| |
|
|
|
| у меня нет задачи определять пользователей за период.
я определяю пользователя в конкретный день. это всегда один пользователь. 2 владельца в один день запрещены. (точне даже в один месяц запрещены, только в исключительных случаях, т.к. счета выставляются за месяц и там общая сумма, и поделить по дням можно только по детализации)
Вашу задачу решать сложнее.
если в мае не было передачи, то апрельская запись очень даже нужная.
т.е. вам нужно объединить 2 запроса
1-й определяет пользоватеЛЯ который использовал телефон на начало периода т.е. дата записи < даты начала периода (top 1 )
2-й определяет пользоватеЛЕЙ которые становились владельцами в течении периода т.е. дата записи >= даты начала периода and <= даты окончания периода даты
ну и объединяете их по UNION | |
|
| |