Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / как написать запрос: через AND или подзапросом? / 13 сообщений из 13, страница 1 из 1
06.04.2009, 13:04
    #35914299
Bananas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Привет.
Есть 2 таблицы: Люди и Перемещение . В первой - ФИО, паспортные данные. Во второй - перемещение между хозяйствами (как-то так - связано с похкнигой, кажется - сам не видел). Причем в Перемещение есть логическое поле умер или нет.
Связь: Люди .id--> Перемещение .f_id.
Цель: вывести все записи из Люди , которые не умерли.
Проблема: не для всех людей есть записи в Перемещение .
Схема:
1. выбрать из Люди все записи, для которых в Перемещение есть записи.
2. выбрать (по рез-ту 1) из Перемещение все записи, где поле статус равно true (жив)

Реализовать схему так:
Код: plaintext
1.
2.
3.
SELECT Name, FIO, ...
        FROM Люди
        WHERE Люди.id=Перемещение.f_id
        AND Перемещение.статус=true;

или тут есть подводные камни и нужно подзапросом (без понятия как)?
...
Рейтинг: 0 / 0
06.04.2009, 13:14
    #35914338
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
BananasПривет.
Есть 2 таблицы: Люди и Перемещение . В первой - ФИО, паспортные данные. Во второй - перемещение между хозяйствами (как-то так - связано с похкнигой, кажется - сам не видел). Причем в Перемещение есть логическое поле умер или нет.
Связь: Люди .id--> Перемещение .f_id.
Цель: вывести все записи из Люди , которые не умерли.
Проблема: не для всех людей есть записи в Перемещение .
Схема:
1. выбрать из Люди все записи, для которых в Перемещение есть записи.
2. выбрать (по рез-ту 1) из Перемещение все записи, где поле статус равно true (жив)

Реализовать схему так:
Код: plaintext
1.
2.
3.
SELECT Name, FIO, ...
        FROM Люди
        WHERE Люди.id=Перемещение.f_id
        AND Перемещение.статус=true;

или тут есть подводные камни и нужно подзапросом (без понятия как)?

Код: plaintext
1.
2.
3.
SELECT Name, FIO, ...
        FROM Люди
        Left join Перемещение on Люди.id=Перемещение.f_id
        AND Перемещение.статус=true AND Жив

Только нужно ещё одно условие по перемещениям - это дана или последняя дата перемещения иначе выскочат все исторические перемещения.
...
Рейтинг: 0 / 0
06.04.2009, 13:17
    #35914345
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Разве если нет перемещения для человека, то он умер?
Мне кажется, что без перемещения человек должен попасть в результирующий набор:
Я бы сделал так:
Код: plaintext
1.
2.
3.
SELECT DISTINCT Люди.Name, Люди.FIO
FROM Люди LEFT JOIN Перемещение ON Люди.id=Перемещение.f_id
WHERE NVL(Перемещение.статус, .F.)
С уважением, Алексей
...
Рейтинг: 0 / 0
06.04.2009, 13:43
    #35914410
PaulWist
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Aleksey-KРазве если нет перемещения для человека, то он умер?
Мне кажется, что без перемещения человек должен попасть в результирующий набор:
Я бы сделал так:
Код: plaintext
1.
2.
3.
SELECT DISTINCT Люди.Name, Люди.FIO
FROM Люди LEFT JOIN Перемещение ON Люди.id=Перемещение.f_id
WHERE NVL(Перемещение.статус, .F.)
С уважением, Алексей

Алексей, с Where получится inner join

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE CURSOR people (f1 int)

CREATE CURSOR PeopleMove (f1_people int, PeopleStatus l)

INSERT INTO people VALUES ( 1 )
INSERT INTO people VALUES ( 2 )
INSERT INTO people VALUES ( 3 )

INSERT INTO peopleMove VALUES ( 1 , .t.)
INSERT INTO peopleMove VALUES ( 2 , .f.)

SELECT DISTINCT People.f1 ;
FROM People LEFT JOIN PeopleMove ON People.f1=PeopleMove.f1_people ;
WHERE NVL(PeopleMove.PeopleStatus, .F.)
...
Рейтинг: 0 / 0
06.04.2009, 13:59
    #35914459
Aleksey-K
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
PaulWistAleksey-KРазве если нет перемещения для человека, то он умер?
Мне кажется, что без перемещения человек должен попасть в результирующий набор:
Я бы сделал так:
Код: plaintext
1.
2.
3.
SELECT DISTINCT Люди.Name, Люди.FIO
FROM Люди LEFT JOIN Перемещение ON Люди.id=Перемещение.f_id
WHERE NVL(Перемещение.статус, .F.)
С уважением, Алексей

Алексей, с Where получится inner join

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
CREATE CURSOR people (f1 int)

CREATE CURSOR PeopleMove (f1_people int, PeopleStatus l)

INSERT INTO people VALUES ( 1 )
INSERT INTO people VALUES ( 2 )
INSERT INTO people VALUES ( 3 )

INSERT INTO peopleMove VALUES ( 1 , .t.)
INSERT INTO peopleMove VALUES ( 2 , .f.)

SELECT DISTINCT People.f1 ;
FROM People LEFT JOIN PeopleMove ON People.f1=PeopleMove.f1_people ;
WHERE NVL(PeopleMove.PeopleStatus, .F.)

Ну тогда так:
Код: plaintext
1.
2.
SELECT DISTINCT People.f1 ;
FROM People LEFT JOIN PeopleMove ON People.f1=PeopleMove.f1_people ;
WHERE ISNULL(PeopleMove.f1_people) OR NVL(PeopleMove.PeopleStatus, .F.)
С уважением, Алексей
...
Рейтинг: 0 / 0
06.04.2009, 14:20
    #35914528
Bananas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Aleksey-K, да, еще этот момент не учел. Выводить всех людей, у которых вообще нет перемещений, либо при последнем перемещении они были живы.

PaulWist, точно, про даты не подумал. Max'ом можно определить последнюю дату?

Код: plaintext
1.
2.
3.
4.
5.
6.
SELECT Name, FIO, ...
FROM Люди
WHERE Люди.id in
    (SELECT f_id
      FROM Перемещение
       WHERE MAX(Перемещение.дата) AND Перемещения.статус=true)
Это когда не выводятся те люди, у которых нет перемещений - часть условия. Сейчас обдумываю, как можно сформировать запрос с полным условием.
...
Рейтинг: 0 / 0
06.04.2009, 14:22
    #35914536
Bananas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Не видел ответов. А одним запросом такое можно сделать?
...
Рейтинг: 0 / 0
06.04.2009, 14:26
    #35914551
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Как правило, при составлении запросов достаточно четко сформулировать что именно вы хотите запросить. Примерно так:

Отобразить список всех людей для которых не указан признак, что они умерли. Т.е. отобразить всех живых людей.

Список людей - это таблица "Люди". А зачем нужна таблица "Перемещение"? Чтобы найти по ней признак того, что человек умер.

Надо ли искать в таблице "Перемещение" все остальные записи для подтверждения того факта, что человек живой? Нет, конечно! Если нет признака, что человек умер, значит он все еще жив.

Следовательно, из таблицы "Перемещение" надо всего-лишь получить подтверждение того факта, что в ней НЕТ записи с признаком "умер". Т.е. очевидно, что это NOT EXISTS().

Код: plaintext
1.
2.
3.
4.
5.
SELECT ...
FROM Люди
WHERE NOT EXISTS(select 'x' from Перемещение 
		WHERE Люди.id=Перемещение.f_id
			AND Перемещение.статус = "умер")

На всякий случай напомню, что если одной записи из таблицы "Люди" соответствует несколько записей из таблицы "Перемещение", то в результате объединения по JOIN вы получите дубли, которые потом придется отсекать по DISTINCT. Что, собственно, и было сделано в приведенных примерах. При использовании NOT EXISTS() такой проблемы нет.
...
Рейтинг: 0 / 0
06.04.2009, 14:41
    #35914588
Bananas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
ВладимирМКак правило, при составлении запросов достаточно четко сформулировать что именно вы хотите запросить.

Напишу требования четче:
Вывести всех людей
1. у которых нет ни одного перемещения (это значит, что они живы)
2. у которых последнее перемещение со статусом жив.

ВладимирМ
Надо ли искать в таблице "Перемещение" все остальные записи для подтверждения того факта, что человек живой? Нет, конечно! Если нет признака, что человек умер, значит он все еще жив.

Понял, с "хронологией" перестарался:)

Вопрос: как вписать в запрос условие 1?
...
Рейтинг: 0 / 0
06.04.2009, 15:51
    #35914817
ВладимирМ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Надо ли понимать эти условия так, что может быть несколько перемещений, причем статусы "мертв" и "жив" могут идти в перемешку? Т.е. сначала переместили "метрв", потом переместили "жив", потом опять переместили "мертв"?

Я это к чему спрашиваю? Если после перемещения "метрв" не может появится никакого другого перемещения, то это одна ситуация. Если может быть несколько перемещений со статусом "мертв" - это другая ситуация. Если статусы могут идти в перемешку, то это третья ситуация.

Если рассматривается сиуация, что перемещение со статусом "мертв" может быть только одно и после него уже не может быть никаких перемещений, то решение "в лоб" будет выглядеть так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT ...
FROM Люди
WHERE NOT EXISTS(select 'x' from Перемещение 
		WHERE Люди.id=Перемещение.f_id
			AND Перемещение.статус = "умер")
	AND
	EXISTS(select 'x' from Перемещение 
		WHERE Люди.id=Перемещение.f_id)

Первый NOT EXISTS() контролирует факт отстутствия перемешения со статусом "мертв", а второй EXISTS() контролирует факт существования хотя бы одного перемещеният вне зависимости от статуса.

Т.е. условие читается так: есть перемещение, но среди всех перемещений нет перемещения со статусом "мертв"

Если надо задействовать еще диапазон дат, то принципиально важным является ответ на вопрос об изменении статуса во времени. Какой статус за каким может оказаться.
...
Рейтинг: 0 / 0
06.04.2009, 16:22
    #35914894
Tohan_ORA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Bananas
Цель: вывести все записи из Люди , которые не умерли.

1. у которых нет ни одного перемещения (это значит, что они живы)
2. у которых последнее перемещение со статусом жив.
Проблема: не для всех людей есть записи в Перемещение .


А может так ???
Выведем людей которые перемещались и никогда не имели статуса умер
и людей которые никогда не перемещались:
Код: plaintext
select * from Люди where id_клиент not in (select id_клиент from перемещение where статус=мертв)
...
Рейтинг: 0 / 0
07.04.2009, 12:34
    #35916688
LUCIAN
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Bananas,
Код: plaintext
1.
2.
3.
4.
SELECT ...
FROM Люди LEFT OUTER JOIN (SELECT Перемещение.f_id,MIN(Перемещение.статус) STATUS ;
 from Перемещение GROUP BY  1  HAVING MIN(Перемещение.статус)=.T.)) TAB1 ;
ON  Люди.id =TAB1.f_id
...
Рейтинг: 0 / 0
10.04.2009, 09:32
    #35924129
Bananas
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как написать запрос: через AND или подзапросом?
Все спасибо за помощь. доберусь до базы, проверю.
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / как написать запрос: через AND или подзапросом? / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]