![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Помогите с запросом SQL interbase [D5, D6, IB6.x]
Pavel_S © (2002-08-22 14:09:00)У меня есть следующие таблицы:
tbl_employees - таблица работников;
tbl_cards - таблица с данными на работников;
В таблице tbl_cards содержаться данные на работников, причем на одного работника может быть несколько карточек (к примеру, если работник начинает работать над другим проектом, то текущая карточка "закрывается" - указывается дата закрытия и выставляется значение поля closed в 1).
Мне нужно сделать следующие запросы:
-возвратить список работников и лишь их последнюю карточку;
-возвратить всех работников с незакрытыми карточками;
-возвратить список работников и лишь их последнюю незакрытую карточку;
Структура таблиц:
tbl_employees:
-employee_id
-name
-last_name
tbl_cards:
-card_id
-employee_id
-project
-closed
-closed_date
Прошу помочь
Pavel_S (2002-08-22 16:17:00) [1]спасибо всем !!!
DmitryK (2002-08-22 16:02:00) [2]
> Тот - это который ? И не стоял вопрос о всех незакрытых
> карт.
2Johnmen ©
тот, на который ты сам ссылался, почитай свои же посты.
2Pavel_S
на второй вопрос, я тебе уже ответил
на третий, используй самый первый запрос, который я тебе прислал
а по первому, если тебе нужны были только имя клиента и код его последней карточи (так бы сразу и писал), то действительно можно воспользоваться тем, что предложил SaS13, только, по моему там есть некоторая избыточность
SELECT e.name, (SELECT MAX(card_id) FROM tbl_cards c WHERE c.employee_id = e.employee_id) FROM tbl_employees e
Pavel_S (2002-08-22 15:44:00) [3]Это ответ на первый вопрос, а как быть с остальными ?
Johnmen (2002-08-22 15:43:00) [4]>DmitryK © (22.08.02 15:39)
>...тот запрос ...
Тот - это который ? И не стоял вопрос о всех незакрытых карт.
Pavel_S (2002-08-22 15:41:00) [5]То есть рабочий запрос:
SELECT e.name, (SELECT c.card_id FROM tbl_cards c WHERE c.employee_id = e.employee_id AND c.card_id = (SELECT MAX(c1.card_id) FROM tbl_cards c1 WHERE c1.employee_id = e.employee_id)) card_id FROM tbl_employees e
Pavel_S (2002-08-22 15:41:00) [6]Более точно запрос был указан SaS13 © - только надо убрать card_id = и поставить уже в конце select"a через пробел
Спасибо SaS13 !!!
DmitryK (2002-08-22 15:39:00) [7]2Johnmen ©
Читайте пожалуйста посты внимательнее, тот запрос вернет все ОТКРЫТЫЕ карточки.
а по заданию - если работник начинает работать над другим проектом, то текущая карточка "закрывается"
DmitryK (2002-08-22 15:36:00) [8]После того, как получен максимальный код карточки для каждого клиента, можно получить и более подробную информацию по клиенту и по данной карточке. Но как это лучше сделать слишком сильно зависит от конкретной реализации. Этот запрос надо будет солидно оптимизировать. Например, если реализовать получение всех данных с помощью единого запроса (соединение таблиц LEFT JOIN), это потребует объединения таблицы tbl_cards самой с собой (возможно IB это реализует легко, а в MSSQL6.5 - это значительно увеличивает время обработки запроса).
Johnmen (2002-08-22 15:35:00) [9]>DmitryK ©
Пожалуйста...
DmitryK © (22.08.02 15:01) возвратит ВСЕ закрытые карточки, а не последнюю.
Чтобы это был ответ на вопрос №2 его надо подправить.
Аналогично и с DmitryK © (22.08.02 15:15)
Да и вообще все варианты бессмысленны, пока не определено "последнюю карточку" !
DmitryK (2002-08-22 15:28:00) [10]2Johnmen ©
> Да нет...Результат одинаков и не соответствует ни одному
> вопросу...
> Но общее направление верно...
Объяснитесь пожалуйста
DmitryK (2002-08-22 15:26:00) [11]-возвратить список работников и лишь их последнюю карточку;
можно сделать еще и так (наверное это будет точнее решать поставленную задачу)
следующий запрос позволяет получить максимальное значение кода карточки для каждогоemployee_id
select employee_id, max(card_id) from tbl_cards
group by employee_id
Johnmen (2002-08-22 15:24:00) [12]>Pavel_S ©
Я вот внимательно прочел вопрос и не понял, что значит
"последнюю карточку" ?
>DmitryK © (22.08.02 15:15)
Да нет...Результат одинаков и не соответствует ни одному вопросу...
Но общее направление верно...
DmitryK (2002-08-22 15:15:00) [13]-возвратить всех работников с незакрытыми карточками;
Точно такой же код, как я привел на первый вопрос, только заменитьLEFT JOINнаINNER JOIN
DmitryK (2002-08-22 15:07:00) [14]В пред. посте если у клиента все карточки закрыты, то возращается NULL в соответствующих полях
SaS13 (2002-08-22 15:02:00) [15]Первое что пришло:
SELECT e.name, card_id = (SELECT c.card_id FROM tbl_cards c WHERE c.employee_id = e.employee_id AND c.card_id = (SELECT MAX(c1.card_id) FROM tbl_cards c1 WHERE c1.employee_id = e.employee_id)) FROM tbl_employees e
DmitryK (2002-08-22 15:01:00) [16]-возвратить список работников и лишь их последнюю карточку;
select e.*, c.* from tbl_employees e LEFT JOIN tbl_cards c on e.employee_id=c.employee_id and c.closed=0
запрос точно будет работать в MSSQL, но по идее должен работать и в IB, если все-таки не пойдет можно сделать так
select e.*, c.* from tbl_employees e LEFT JOIN tbl_cards c on e.employee_id=c.employee_id
where c.closed=0
обращаю внимание наc.closed=0, я предпалагаю, что незакрытая карточка помечается как 0. Можно было бы написатьc.closed<>1, но тогда врядли удастся использовать индексы.
Ivt_ (2002-08-22 14:59:00) [17]Помоему первый запрос реализовать нельзя.
По какому критерию ты определишь последнюю карточку?
Val (2002-08-22 14:58:00) [18]>Pavel_S © (22.08.02 14:45)
смотря как связаны, я говорил об отношении many-to-many
Pavel_S (2002-08-22 14:45:00) [19]>> лучше использовать классическую таблицу-развязку
А если у меня еще таблиц двадцать и все связаны с tbl_employees ?
Помогите с запросами, хотябы первый.
Val (2002-08-22 14:21:00) [20]как-то уж вы мало задали, заказали бы задачу сразу.
по структуре: поле closed лишнее, поскольку, если closed_date is not null => то это и говорит, что карточка закрыта. работник ведь может в принципе участвовать в нескольких проектах сразу?
лучше использовать классическую таблицу-развязку
link_emp_cards:
-employeeid
-cardid
а из карточек employeeid убрать.