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

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

Помогите с запросом 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 убрать.


Наверх

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