Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2007.08.26;
Скачать: [xml.tar.bz2];

Вниз

"Вложенное" условие на SQL   Найти похожие ветки 

 
Ламот ©   (2007-07-25 15:50) [0]

День добрый.
Подскажите пож., никак не соображу, есть 2 таблицы, в одной клиенты:

kod (уникальный)
name (Ф.И.О./название организации)
stat (Статус: частные/физ./бюджетники)
etc...

в другой услуги, на которые подписанны эти клиенты:

kod (из таблицы "клиенты")
skod (уникальный)
date_begin (дата начала услуги)
date_close (дата отключения услуги)
etc...

необходимо выбрать всех клиентов, кто подключился с 01.06.2007 по 01.07.2007, попробовал "в лоб":

select b.kod, a.name, b.date
from клиент а, услуги b
where b.date_begin between 01.06.2007 and 01.07.2007;

Фигня получается, потому что:
1. В результирующую таблицу клиенты попадают столько раз, сколько услуг он себе приобрёл за указанный интервал времени.
2. Так же попадают клиенты, которые у нас уже были, но в указанный диапазон времени подключились еще на какую-то услугу.

Решить 1 проблему пробовал через distinct, но тут опять сложность, если выбирать ТОЛЬКО kod и name - срабатывает, если добавить в select еще и date_begin - все, при разных датах заключения услуги - клиент будет задваиваться.
С какого боку подойти к решению второй проблемы - совсем не знаю... я так предпологаю, что нужно составить запрос в запросе (наподобии вложенных циклов), но как это делается не знаю, а может еще и не в том направлении думаю!
В общем - направьте пож. мысль в правильное русло.
И если кто может поделиться хорошим "самоучителем" на русском языке по SQL в целом, и по postgres sql в частности - буду очень признателен! ))


 
ZugZug   (2007-07-25 16:12) [1]

Как отличаешь подключение услуги от первоначального подключения клиента?

Попробуй использовать функцию min для выбора минимальной даты.
Используй приведенный тобой запрос как view и выбирай из него (подставь его в секцию from объемлющего запроса).

В приведенном запросе отсутствует связь между таблицами по первичному ключу.


 
Petr V. Abramov ©   (2007-07-25 16:12) [2]

в лоб -


select b.kod, a.name, min(b.date)
from клиент а, услуги b
group by  b.kod, a.name
having min(b.date_begin) between 01.06.2007 and 01.07.2007

вроде ANSI SQL соответствует
но это совсем в лоб, работать не быстро будет


 
Desdechado ©   (2007-07-25 16:14) [3]

Неплохо бы соединить таблицы в запросе по полю kod
Читать JOIN в справке по SQL


 
Petr V. Abramov ©   (2007-07-25 16:14) [4]

> Petr V. Abramov ©   (25.07.07 16:12) [2]
select b.kod, a.name, min(b.date)
from клиент а, услуги b
where a.kod = b.kod
group by  b.kod, a.name
having min(b.date_begin) between 01.06.2007 and 01.07.2007


 
Vlad Oshin ©   (2007-07-25 16:16) [5]

select * from Client
where Client.Kod in
(
select Usluga.Kod from Usluga
where date_begin between 01.06.2007 and 01.07.2007;
)

а так если?


 
Petr V. Abramov ©   (2007-07-25 16:30) [6]

> Vlad Oshin ©   (25.07.07 16:16) [5]
так дубли уйдут, но полезут клиенты, которые подключились раньше начала периода, а в периоде заказли еще одну услугу


 
Ламот ©   (2007-07-25 16:40) [7]

Спасибо всем, общую идею понял, дальше буду разбираться сам. )))

Вопрос про "самоучители" остается открытым (особенно касательно postgres sql"a). Все, что находил до этого, либо "классический SQL", либо на английском, а с ним у меня тоже проблемы имеются...


 
wicked ©   (2007-07-25 20:24) [8]

добавлю

> Vlad Oshin ©   (25.07.07 16:16) [5]

> select * from Client
> where Client.Kod in
> (
> select Usluga.Kod from Usluga
> where date_begin between 01.06.2007 and 01.07.2007;
> )

избегайте таких конструкций - эквивалентная ей конструкция с exists работает иногда на порядок быстрее


 
Мазут Береговой ©   (2007-07-25 23:15) [9]

Как насчет такого:

select b.kod, a.name, b.date
from клиент а
inner join услуги b on a.kod = b.kod
where b.date_begin between 01.06.2007 and 01.07.2007;


или по-старинке:

select b.kod, a.name, b.date
from клиент а, услуги b
where b.date_begin between 01.06.2007 and 01.07.2007 and a.kod = b.kod;


 
Мазут Береговой ©   (2007-07-25 23:19) [10]

В любом случае решение будет давать по всем услугам результат, потому что нет критерия на выборку по услугам. Надо подключать или таблицу услуг и ставить условие, или условие, если услуги в таблице b...


 
Ламот ©   (2007-07-26 09:59) [11]

wicked © [8]
"exists"
Мазут Береговой © [9]
"inner join"
- Люди, спасибо большое за участие, со своей задачей я уже разобрался, а до понимания приведенных инструкций я, к сожалению, пока не дорос... !! )))

Сейчас добрался до: "МАРТИН ГРУБЕР Понимание SQL", если кто-то может посоветовать что-то еще (на русском, и с postgres’овской спецификацией), буду шибко благодарен! ))))



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2007.08.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.046 c
11-1168515485
Mabia
2007-01-11 14:38
2007.08.26
Установка Report&Print в D6


2-1186069152
-==\AnGnA/==-
2007-08-02 19:39
2007.08.26
Куча вопросов


2-1186210510
Poroshm
2007-08-04 10:55
2007.08.26
как создать второе окно?


5-1159188378
Rat Rat
2006-09-25 16:46
2007.08.26
Перерисовка, TCanvas и стандартные компоненты.


15-1185860176
Кирей
2007-07-31 09:36
2007.08.26
как победить рутинные операции





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский