Интересный вопрос знатокам SQL

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Интересный вопрос знатокам SQL

Сообщение astoro » 23.03.2004 (Вт) 10:37

Есть две таблицы


Первая Tab1 содержит два поля

IDChel - ID Человека

ChelName - Имя человека


Вторая Tab2 тоже содержит два поля

IDChelFromTab1 - ID человека из первой таблицы

SobDate - Дата какого-либо события (например, человеку дают зарплату, или щелбан, возможно не один раз в месяц)


Для Выборки людей, которым в допустим в марте щелбаны уже ставили строка SQL такая:


SELECT DISTINCT Tab1.ChelName, Tab2.SobDate FROM Tab1, Tab2 WHERE Tab1.IDChel=Tab2.IDChelFromTab1 AND Tab2.SobDate BETWEEN #03/01/04# AND #03/31/04#


Вопрос следующий: как сделать выборку людей, которым щелбан в марте не ставили вовсе???

Если поставить перед BETWEEN слово NOT, то в выборку попадают люди, которым щелбан ставили раньше, т.к. они удовлетворяют условию NOT BETWEEN по более ранним записям талицы Tab2, и не попадают только те, которым щелбан вообще никогда не ставили.

areh
Постоялец
Постоялец
 
Сообщения: 530
Зарегистрирован: 02.12.2002 (Пн) 12:28
Откуда: РОССИЯ, Салехард

Сообщение areh » 23.03.2004 (Вт) 10:52

на сколько я понимаю, вот так должно работать:

SELECT DISTINCT Tab1.ChelName, Tab2.SobDate FROM Tab1, Tab2 WHERE Tab1.IDChel=Tab2.IDChelFromTab1 AND NOT(Tab2.SobDate BETWEEN #03/01/04# AND #03/31/04#)

astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Сообщение astoro » 23.03.2004 (Вт) 11:34

Результат к сожалению тот же, что и при NOT BETWEEN.
:cry:

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 23.03.2004 (Вт) 12:30

Код: Выделить всё
SELECT DISTINCT Tab1.ChelName
FROM Tab1
WHERE NOT EXISTS
(
   SELECT DISTINCT Tab2.IDChelFromTab1
   FROM Tab2
   WHERE Tab2.SobDate BETWEEN #03/01/04# AND #03/31/04#
)

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.03.2004 (Вт) 13:05

skiperski, ты забыл связать поля IDChel.
Я бы сделал так:
Код: Выделить всё
select Tab1.ChelName
from Tab1
where NOT EXISTS
  (
    select 1
    from Tab2
    where Tab2.SobDate BETWEEN #03/01/04# AND #03/31/04#
[b]      and Tab2.IDChelFromTab1 = Tab1.IDChel[/b]
  )
Lasciate ogni speranza, voi ch'entrate.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 23.03.2004 (Вт) 15:21

По-моему, это лишнее. Все из первой, кроме тех кто уже получил чего там ему положено. А уж есть они во второй или нет - не наше дело.

astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Сообщение astoro » 23.03.2004 (Вт) 15:50

Запрос в скобках никогда не будет пустым если есть хоть одна запись о щелбанах за Март в Tab2. Поэтому результат всего запроса - пустой рекордсет. :( :( :(

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 23.03.2004 (Вт) 16:25

А можно конкренто, какие люди должны попасть в запрос?
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Сообщение astoro » 23.03.2004 (Вт) 16:29

А если вместо NOT EXISTS поставить NOT IN, то это вызывает у компа головную боль, ждал минут десять, так результата и не дождался :( .

astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Сообщение astoro » 23.03.2004 (Вт) 16:32

В запросе должны быть все те люди, которые не фигурируют в Tab2 в диапазоне дат #03/01/04# AND #03/31/04#, все люди по одному разу.

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 23.03.2004 (Вт) 16:42

alibek прав, надо связать таблицы.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 23.03.2004 (Вт) 16:44

Может тогда использовать minus?
Код: Выделить всё
select DISTINCT IDChel As ID
from Tab1

MINUS

select DISTINCT IDChelFromTab1 As ID
from Tab2
Where ...
Lasciate ogni speranza, voi ch'entrate.

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 23.03.2004 (Вт) 17:02

А у меня первый вариант alibek'а с NOT EXISTS нормально работает... :roll:
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)

skiperski
Идеолог
Идеолог
Аватара пользователя
 
Сообщения: 1386
Зарегистрирован: 25.06.2002 (Вт) 15:52

Сообщение skiperski » 23.03.2004 (Вт) 17:34

Я уже признался, что был не прав :oops:

Sebas
Неуловимый Джо
Неуловимый Джо
Аватара пользователя
 
Сообщения: 3626
Зарегистрирован: 12.02.2002 (Вт) 17:25
Откуда: столько наглости такие вопросы задавать

Сообщение Sebas » 23.03.2004 (Вт) 20:50

SELECT Tab1.ChelName FROM Tab1 LEFT JOIN Tab2 ON Tab1.IDChel=Tab2.IDChelFromTab1 WHERE NOT(Tab2.SobDate BETWEEN #03/01/04# AND #03/31/04#)

помойму всё...

Tab1.IDChel=Tab2.IDChelFromTab1 вот это не надо в условие отбора ставить...
- Я никогда не понимал, почему они приходят ко мне чтобы умирать?

sebas<-@->mail.ru

astoro
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 23.03.2004 (Вт) 10:31

Сообщение astoro » 24.03.2004 (Ср) 7:00

Всем большое спасибо за помощь. Очень рад встретить такую отзывчивость к новичку. :D

Rainbow
Человек-радуга
Человек-радуга
 
Сообщения: 543
Зарегистрирован: 13.05.2003 (Вт) 14:16

Сообщение Rainbow » 24.03.2004 (Ср) 11:08

skiperski писал(а):Я уже признался, что был не прав :oops:

skiperski, я же не к тому... Правильный ответ есть, а что еще надо, собственно?
Ты, главное, не пропадай надолго :)

А "LEFT JOIN" с условием, "NOT EXISTS" и еще "NOT IN" - это все эквиваленты одного и того же. Так что Sebas тоже прав.
Учиться - значит открывать для себя то, что уже знаешь. <...> Учить - значит напоминать другим о том, что они знают это также хорошо, как и ты. <...> Лучше всего ты учишь тому, чему тебе самому больше всего надо научиться. (Р. Бах)


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 2

    TopList