Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Составление SQL-запросов > определить колличесвто


Автор: Samotnik 29.9.2009, 00:29
Привет, есть такая Б.д,
Код

CREATE TABLE skidki(
Velichina INTEGER NOT NULL,
name_nazvanie_skidki varchar2(32) NOT NULL
CONSTRAINT ogranichenie1 PRIMARY KEY,
kompany VARCHAR2(32) NOT NULL,
vremy_d VARCHAR2(32) NOT NULL
); 

CREATE TABLE samoleti (
type_samoleta varchar2(32) NOT NULL
CONSTRAINT ogranichenie3 PRIMARY KEY,
kompany VARCHAR2(32) NOT NULL,
chasy_naleta INTEGER,
god_vipyska date NOT NULL,
kolichestvo_mest INTEGER 
); 

CREATE TABLE bileti (
nomer_reysa INTEGER 
CONSTRAINT ogranichenie5 PRIMARY KEY
CONSTRAINT ogranichenie6  CHECK (nomer_reysa > 0),
klass VARCHAR2(32) NOT NULL,
mesto INTEGER,
stoimost number(6),
name_nazvanie_skidki varchar2(32) NOT NULL
CONSTRAINT ogranichenie7 
REFERENCES skidki(name_nazvanie_skidki )
); 

CREATE TABLE reysi (
prodannie_bileti INTEGER,
nomer_reysa INTEGER 
CONSTRAINT ogranichenie8 
REFERENCES bileti(nomer_reysa),
pynkt_naznacheniya varchar2(32) NOT NULL,
data_vileta date NOT NULL,
vremya_vileta VARCHAR2(32) NOT NULL,
type_samoleta VARCHAR2(32) NOT NULL
CONSTRAINT ogranichenie9
REFERENCES samoleti(type_samoleta)
); 


INSERT INTO skidki VALUES (10, 'den pobedi', 'aeroflot', 'july' );
INSERT INTO skidki VALUES (15, 'vse na otdix', 'belavia', 'july-august' );
INSERT INTO skidki VALUES (7, 'studencheskie', 'lot', 'January-february' );
INSERT INTO skidki VALUES (20, 'goryachee predlojenie', 'luftganze', '10july-25july' );
INSERT INTO samoleti VALUES ('boeng_747', 'aeroflot', 25000, '22.02.1998', 450);
INSERT INTO samoleti VALUES ('ty_154', 'Transitr', 68000, '5.07.1988', 300);
INSERT INTO samoleti VALUES ('airbus_a_380', 'luftganze', 15000, '13.09.1998', 250);
INSERT INTO samoleti VALUES ('concorde', 'lot', 68000, '5.07.2000', 150);
INSERT INTO bileti VALUES (314, 'perviy', 28,315, 'den pobedi');
INSERT INTO bileti VALUES (205, 'ekonom', 76,177, 'goryachee predlojenie');
INSERT INTO bileti VALUES (76, 'ekonom', 82,230, 'studencheskie');
INSERT INTO bileti VALUES (228, 'vtoroy', 47,350, 'vse na otdix');
INSERT INTO reysi VALUES (17,314, 'Parij', '25.09.2009', '19:00', 'airbus_a_380');
INSERT INTO reysi VALUES (28,205, 'Milan', '07.10.2009', '13:00', 'boeng_747');
INSERT INTO reysi VALUES (56,76, 'Moscow', '07.08.2009', '23:00', 'ty_154');
INSERT INTO reysi VALUES (33,228, 'Moscow', '29.06.2009', '23:00', 'concorde');


нужно определить сколько билетов было продано на ближайший рейс до Москвы.
 smile   smile 
Буду признателен за помощь  smile  репой 

Автор: Gluttton 29.9.2009, 01:18
Привет!
Круто, я пишу самому Samotnik'y!

Цитата(Samotnik @  29.9.2009,  00:29 Найти цитируемый пост)
есть такая Б.д,

Возможно я уже устал, но мне кажеться, что вполне достаточно одной таблицы:
Код

CREATE TABLE reysi (
prodannie_bileti INTEGER,
nomer_reysa INTEGER 
CONSTRAINT ogranichenie8 
REFERENCES bileti(nomer_reysa),
pynkt_naznacheniya varchar2(32) NOT NULL,
data_vileta date NOT NULL,
vremya_vileta VARCHAR2(32) NOT NULL,
type_samoleta VARCHAR2(32) NOT NULL
CONSTRAINT ogranichenie9
REFERENCES samoleti(type_samoleta)
); 

И если это так, то вот такой вот запрос:
Код

select PRODANNIE_BILETI
from REYSI
    where PYNKT_NAZNACHENIYA='Moscow'
    and VREMYA_VILETA=
    (
        select min(VREMYA_VILETA)
        from REYSI
            where DATA_VILETA=
            (
                select min(DATA_VILETA)
                from REYSI
            )
    )
    and DATA_VILETA=
    (
        select min(DATA_VILETA)
        from REYSI
    )

Вернет вот такие вот данные:
Цитата

PRODANNIE_BILETI
33

Что, помоему правильно...
Важно отметить, что запрос не учитывает "настоящее время", т.е. ближайший рейс запросто может оказаться в прошлом...
Если это нужно учесть, то прошу указать СУБД (хотя итак видно, что не мой любимый Firebird smile ).

Добавлено через 14 минут и 35 секунд
Усилил тестовые данные...
Код

INSERT INTO reysi VALUES (44,76, 'Moscow', '07.08.2009', '22:00', 'ty_154');
INSERT INTO reysi VALUES (13,228, 'Moscow', '29.06.2009', '21:00', 'concorde');
INSERT INTO reysi VALUES (52,76, 'Moscow', '07.08.2009', '19:00', 'ty_154');
INSERT INTO reysi VALUES (37,228, 'Moscow', '29.06.2009', '22:00', 'concorde');

Запрос вернул:
Цитата

13

Т.е. вроде всё правильно...

Автор: Deniz 29.9.2009, 05:36
Gluttton, как-то сложно получилось.
Действительно достаточно только рейсов, если я правильно понял структуры БД.
А вот так не пойдет? СУБД не указана, поэтому ...
Код
select top 1 prodannie_bileti from reysi where pynkt_naznacheniya = 'Moscow' order by data_vileta, vremya_vileta

vremya_vileta хранить в varchar не очень хорошо.

Автор: Gluttton 29.9.2009, 07:13
Цитата(Deniz @  29.9.2009,  05:36 Найти цитируемый пост)
А вот так не пойдет?

Ну здрасте! Конечно же нет! Ты что думаешь, что Samotnik написал такой длинный вопрос, что бы в ответ получить одну строчку кода smile !? Шучу smile  ...
А на самом деле, действительно, твой запрос будет попроще, проверил на своей БД - возвращает 13...

Добавлено через 2 минуты и 19 секунд
Цитата(Deniz @  29.9.2009,  05:36 Найти цитируемый пост)
СУБД не указана, поэтому ...

Адаптировать по конкретную СУБД, можно, почитв http://ru.wikipedia.org/wiki/Select_(SQL)... В частности для Firebird это будет first...

Автор: Deniz 29.9.2009, 08:32
Цитата(Gluttton @  29.9.2009,  10:13 Найти цитируемый пост)
Ты что думаешь, что Samotnik написал такой длинный вопрос, что бы в ответ получить одну строчку кода
бывает сидишь и не понимаешь, что нужно сделать, строишь громадные запросы и т.д., а все оказывается очень просто, достаточно свежего взгляда ... и дыхания  smile
Цитата(Gluttton @  29.9.2009,  10:13 Найти цитируемый пост)
Адаптировать по конкретную СУБД, можно
ели бы знать под что адаптировать.
Подождем что скажет Samotnik, может есть еще какие-то условия.

Автор: Zloxa 29.9.2009, 08:51
Парни, чтобы найти ближайший  рейс, ранжироваться надо по абсолюту разницы между сейчас и датой вылета.
Вы же ищите самый ранний рейс на москву. smile

Samotnik, арифметика дат специфична для платформы. Озвучь плиз платформу.

Автор: Gluttton 29.9.2009, 09:05
Цитата(Zloxa @  29.9.2009,  08:51 Найти цитируемый пост)
Парни, чтобы найти ближайший  рейс, ранжироваться надо по абсолюту разницы между сейчас и датой вылета.Вы же ищите самый ранний рейс на москву. 

Я об этом честно предупреждал  smile ...

Цитата(Gluttton @  29.9.2009,  01:18 Найти цитируемый пост)
Важно отметить, что запрос не учитывает "настоящее время", т.е. ближайший рейс запросто может оказаться в прошлом...


Для моего случая необходимо внутри условий WHERE добавить соответсвенно:
(псевдокод)
Код

and DATA_VILETA >= date(now)
...
and VREMYA_VILETA >= time(now)

Во втором примере можно добавить десять минут к правой части условия и это будет соответсововать тому, что например до отправки осталось десять минут и посадка окончена...

Автор: Zloxa 29.9.2009, 09:14
Цитата(Gluttton @  29.9.2009,  09:05 Найти цитируемый пост)
добавить соответсвенно

smile))
Это будет ближайший будущий рейс smile
что ближе к нулю - минус единица или шесть? smile

Вооще я просто к словам придираюсь

Автор: Deniz 29.9.2009, 10:53
Да уж, что-то мы с текущей датой ... забыли.
Ждем Samotnik для разъяснений задачи.

Автор: Gluttton 29.9.2009, 14:44
 smile 

Цитата(Zloxa @  29.9.2009,  09:14 Найти цитируемый пост)
Это будет ближайший будущий рейс 

Ага приходишь так себе на ж\д воказл, купил белет на ближайший поезд, вышел на пирон... а поезд то оказывается ушел ещё два часа назад  smile ...

Цитата(Zloxa @  29.9.2009,  09:14 Найти цитируемый пост)
Вооще я просто к словам придираюсь

Всё правильно - никаких двояких толкований!

Автор: Samotnik 30.9.2009, 00:14
Deniz,  твой способ не работает ((((    
Цитата

Error at line 1: ora-00923: ключевое слово from не найдено там, где оно ожидалось

Gluttton,  СПАСИБО !!!!  smile  Работает !

Автор: Zloxa 30.9.2009, 07:29
Цитата(Samotnik @  30.9.2009,  00:14 Найти цитируемый пост)
ora

ухты, Samotnik на ораклю перешел ;))
Что ж ты так сразу и не сказал?
Код

select * from 
  (select /*+first_rows(1)*/t.*, row_number() over (order by to_date(data_vileta||' '||vremya_vileta,'DD.MM.YYYY HH24:MI'))  rn
    from reysi t where to_date(data_vileta||' '||vremya_vileta,'DD.MM.YYYY HH24:MI') >= sysdate)
wehre rn = 1

Для пущего перфомансу запросу добавить индекс:
Код

create reysi $date$idx on reysi (to_date(data_vileta||' '||vremya_vileta,'DD.MM.YYYY HH24:MI'));


Но лучше, конечно, дату хранить как дату а не как строку.

Автор: Samotnik 30.9.2009, 18:20
Цитата(Zloxa @  30.9.2009,  07:29 Найти цитируемый пост)
ухты, Samotnik на ораклю перешел ;))

 smile  
не, это не мне, это друг попросил, ему лабу в универе здавать. Я кое что сам помог, а в остально ковырятся особо времени нету smile 
Спасибо, еще раз, перешлю ему щас этот код - хай тестит smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)