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

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

или тут есть подводные камни и нужно подзапросом (без понятия как)?
...
Рейтинг: 0 / 0
как написать запрос: через AND или подзапросом?
    #35914338
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
как написать запрос: через AND или подзапросом?
    #35914345
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разве если нет перемещения для человека, то он умер?
Мне кажется, что без перемещения человек должен попасть в результирующий набор:
Я бы сделал так:
Код: plaintext
1.
2.
3.
SELECT DISTINCT Люди.Name, Люди.FIO
FROM Люди LEFT JOIN Перемещение ON Люди.id=Перемещение.f_id
WHERE NVL(Перемещение.статус, .F.)
С уважением, Алексей
...
Рейтинг: 0 / 0
как написать запрос: через AND или подзапросом?
    #35914410
PaulWist
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
как написать запрос: через AND или подзапросом?
    #35914459
Фотография Aleksey-K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
как написать запрос: через AND или подзапросом?
    #35914528
Bananas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
как написать запрос: через AND или подзапросом?
    #35914536
Bananas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не видел ответов. А одним запросом такое можно сделать?
...
Рейтинг: 0 / 0
как написать запрос: через AND или подзапросом?
    #35914551
Фотография ВладимирМ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как правило, при составлении запросов достаточно четко сформулировать что именно вы хотите запросить. Примерно так:

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

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

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

Следовательно, из таблицы "Перемещение" надо всего-лишь получить подтверждение того факта, что в ней НЕТ записи с признаком "умер". Т.е. очевидно, что это 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
как написать запрос: через AND или подзапросом?
    #35914588
Bananas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирМКак правило, при составлении запросов достаточно четко сформулировать что именно вы хотите запросить.

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

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

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

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

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

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

Код: 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
как написать запрос: через AND или подзапросом?
    #35914894
Tohan_ORA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Bananas
Цель: вывести все записи из Люди , которые не умерли.

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


А может так ???
Выведем людей которые перемещались и никогда не имели статуса умер
и людей которые никогда не перемещались:
Код: plaintext
select * from Люди where id_клиент not in (select id_клиент from перемещение where статус=мертв)
...
Рейтинг: 0 / 0
как написать запрос: через AND или подзапросом?
    #35916688
LUCIAN
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
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
как написать запрос: через AND или подзапросом?
    #35924129
Bananas
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все спасибо за помощь. доберусь до базы, проверю.
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / как написать запрос: через AND или подзапросом?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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