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

Вниз

SQL-запрос для выборки данных   Найти похожие ветки 

 
serguncho ©   (2005-07-22 22:47) [0]

Добрый вечер!

Помогит разрешите проблему с запросом, пожалуйста.

Имею таблицу (tablica) c полями
NOMER_CLENA INTEGER,  
POL_CLENA   VARCHAR(1), /может быть М (мальчОнка) или F (девчОнка)/
CARD_CLENA VARCHAR(5), /пол+номер, например, F4/
RAITING FLOAT,
...

Мне нужно выбрать две самых рейтинговых дивчины и два самых-самых парня.

Думал сначала отсортировать по рейтингу и выбрать 4 души:
select first 4(*) from tablica order by RAITING

но понял ошибку, т.к. могут получиться 4 парня или 3 девушки и один парень, а никак не 50/50.

Подскажите, как организовать грамотный запрос по выборке людей (причем кол-во может быть и не пропорционально 1\1, а, например, 3 девушки- и 2 парня-лидера).


 
sniknik ©   (2005-07-22 23:45) [1]

union в файрбирде дозволяются? вот и выбирай в 2 запроса раздельно для M и Ж обьедененняя их union-ом. (чтобы не получилось в сумме 8 выбирай по 2 ;)


 
serguncho ©   (2005-07-23 09:06) [2]

Union работает. Спасибо за подсказку.
Но я чего не могу им правильно пользоваться.

select first 2 * from TABLICA where POL_CLENA="m"
union
select first 2 * from TABLICA where POL_CLENA="f"
ORDER BY 7

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


 
P.N.P. ©   (2005-07-23 09:28) [3]

>serguncho ©   (23.07.05 09:06) [2]
Как у тебя рейтинг начисляется?
Может можно сделать что-то вроде
select first 2 * from TABLICA where POL_CLENA="m"
and RAITING>
(select max(RAITING) from TABLICA where
POL_CLENA="m")-какое_то_число
union
select first 2 * from TABLICA where POL_CLENA="f"
and RAITING>
(select max(RAITING) from TABLICA where
POL_CLENA="f")-какое_то_число
ORDER BY 7


 
serguncho ©   (2005-07-23 09:52) [4]

Как у тебя рейтинг начисляется?
-------------------------------
6 вариантов - посетил:
1)5 занятий (каждый день): 100
2)4 занятия              :  80
3)3 заняти               :  60
4)2 занятия              :  40
5)1 занятие              :  20  
6)0 занятий              :   0
-------------------------------
Так что сравнивать с каким-то значением, наверное, просто так будет сложно. Особенно, если пионеры - заядлые прогульщики.
Можно, конечно, предварительно отсортировать их и в качестве параметров (для дальнейшего сравнения по Вашему коду) загнать значение 3-х парней и дам, но и тут можно получить косяк, т.к. у у 3 и 2 могут быть одинаковые значения рейтинга.


 
P.N.P. ©   (2005-07-23 10:43) [5]

А если процедуру сделать?

SET TERM ^ ;

CREATE PROCEDURE GET_RAITING (
   COUNT_M INTEGER,
   COUNT_F INTEGER,
   INACCURACY FLOAT)
RETURNS (
   NC INTEGER,
   POL VARCHAR(1),
   CARD VARCHAR(5),
   RAIT FLOAT)
AS
DECLARE VARIABLE MAX_RAITING FLOAT; /* Максимальный рейтинг */
DECLARE VARIABLE M_CNT INTEGER; /* Счетчик М */
DECLARE VARIABLE F_CNT INTEGER; /* Счетчик Ж */
begin
if (count_m<1 or count_f<1) then
   exit;
select max(raiting)-:inaccuracy from table1 into :max_raiting;
m_cnt=0;
f_cnt=0;
for select t.nomer_clena,t.pol_clena,t.card_clena,t.raiting from table1 t
  where t.raiting>=:max_raiting into :nc, :pol, :card, :rait
    do
      begin
         if (pol="M" and m_cnt<count_m) then
         begin
          m_cnt=m_cnt+1;
          suspend;
            end
         if (pol="F" and f_cnt<count_f) then
         begin
          f_cnt=f_cnt+1;
          suspend;
            end
        if (m_cnt=count_m and f_cnt=count_f) then
         exit;
      end
end
^

SET TERM ; ^

DESCRIBE PARAMETER NC PROCEDURE GET_RAITING
"Номер";
DESCRIBE PARAMETER POL PROCEDURE GET_RAITING
"Пол";
DESCRIBE PARAMETER CARD PROCEDURE GET_RAITING
"Пол+номер";
DESCRIBE PARAMETER RAIT PROCEDURE GET_RAITING
"Рейтинг";
DESCRIBE PARAMETER COUNT_M PROCEDURE GET_RAITING
"Кол-во мужчин";
DESCRIBE PARAMETER COUNT_F PROCEDURE GET_RAITING
"Кол-во женщин";
DESCRIBE PARAMETER INACCURACY PROCEDURE GET_RAITING
"Погрешность";


 
sniknik ©   (2005-07-23 11:42) [6]

почему тогда не так?
select first 2 * from TABLICA where POL_CLENA="m" ORDER BY 7
union
select first 2 * from TABLICA where POL_CLENA="f" ORDER BY 7


 
serguncho ©   (2005-07-23 11:52) [7]

sniknik © [6]
почему тогда не так?
select first 2 * from TABLICA where POL_CLENA="m" ORDER BY 7
union
select first 2 * from TABLICA where POL_CLENA="f" ORDER BY 7
---------
Ругается на такую команду.

P.N.P. ©  [5]
Спасибо. Протестирую и проинформирую о результатах. Хотя все это громоздко. Хотелось чего-то простого, как г-н sniknik написал. Не работает, увы!


 
Anatoly Podgoretsky ©   (2005-07-23 12:57) [8]

select first 2 * from TABLICA where POL_CLENA="m"
union
select first 2 * from TABLICA where POL_CLENA="f"
ORDER BY поле поле, поле рейтинг


 
Anatoly Podgoretsky ©   (2005-07-23 12:58) [9]

sniknik ©   (23.07.05 11:42) [6]
ORDER BY в ANSI SQL может применяться только для результата


 
sniknik ©   (2005-07-23 15:24) [10]

Anatoly Podgoretsky ©   (23.07.05 12:58) [9]
это я знаю (так сказать смутно догадываюсь что ограничения какието есть ;о)))
но кто сказал что файрбирд это чистый ANSI SQL? (возможно конечно, я с ним не так часто общаюсь... не в курсе тонкостей)
может и позволяет... почему не проверить.

и сказал поэтому предположительно, попробовать, был бы аксесс сказал бы точнее ;о)) там можно так
SELECT * FROM (select TOP 2 * from TABLICA where POL_CLENA="m" ORDER BY 7)
union
SELECT * FROM (select TOP 2 * from TABLICA where POL_CLENA="f" ORDER BY 7)


 
Anatoly Podgoretsky ©   (2005-07-23 15:31) [11]

sniknik ©   (23.07.05 15:24) [10]
А я именно потому и подчеркнул, ANSI, поскольку тоже не хзнаю насколько он ANSI.
Ну а по поводу применения к результату, так логично же :-)
Порядок применяется к выдаваемому набору иначе не порядок.
По вопросу видно, что надо два М и два Ж и далее по рейтингу.
Большего он не сказал, а то есть еще и более хитрые методы.


 
Nikolay M. ©   (2005-07-23 16:43) [12]


> serguncho ©

А как выбирать, если у всех рейтинг одинаковый?


 
serguncho ©   (2005-07-23 16:56) [13]

Nikolay M. ©   (23.07.05 16:43) [12]

А как выбирать, если у всех рейтинг одинаковый?
----
Не бойтесь, пиписьками меряться не будут :-))
КОнечно по алфавиту, но не столько важно, т.к. я не могу даже обычного запроса сделать.

sniknik ©   (23.07.05 15:24) [10]
и сказал поэтому предположительно, попробовать, был бы аксесс сказал бы точнее ;о)) там можно так
SELECT * FROM (select TOP 2 * from TABLICA where POL_CLENA="m" ORDER BY 7)
union
SELECT * FROM (select TOP 2 * from TABLICA where POL_CLENA="f" ORDER BY 7)
----
Не работает. Как я понял Файрберд не работает с вложенными запросами. Если кто знает, как работать - подскажите. Т.к. вл. запросы точно бы проблему решили


 
Nikolay M. ©   (2005-07-23 19:05) [14]


> serguncho ©   (23.07.05 16:56) [13]
> КОнечно по алфавиту

Что по алфавиту? Ф? И? О? И почему "конечно"?

А так ФБ поймет?
SELECT * FROM TABLICA WHERE ID IN (select TOP 2 ID from TABLICA where POL_CLENA="m" ORDER BY 7)
union
SELECT * FROM TABLICA WHERE ID IN (select TOP 2 ID from TABLICA where POL_CLENA="f" ORDER BY 7)


 
serguncho ©   (2005-07-23 19:11) [15]

Nikolay M. ©   (23.07.05 19:05) [14]
----------
Шикарно. Огромное спасибо за разрешение проблемы.


 
serguncho ©   (2005-07-23 19:13) [16]

> КОнечно по алфавиту

Что по алфавиту? Ф? И? О? И почему "конечно"?
------
В запарке некорректно отписался - по Имени М иди Ж, но это уже понятно, что вторым полем упорядочивания ставить.


 
Nikolay M. ©   (2005-07-23 19:39) [17]

Пыж. Сортировку, я еще подозреваю, надо все-таки DESC указать?


 
Deniz ©   (2005-07-25 06:35) [18]

А чем вам ответ Anatoly Podgoretsky ©   (23.07.05 12:57) [8] не нравится, или никак попробовать не получается?
select first 2 POL_CLENA, RAITING, ... from TABLICA where POL_CLENA="m"
union
select first 2 POL_CLENA, RAITING, ... from TABLICA where POL_CLENA="f"
ORDER BY 1, 2 desc, ...


 
Johnmen ©   (2005-07-25 09:15) [19]

Самый верный и простой ответ Deniz ©   (25.07.05 06:35) [18].

А ещё интересно, что такое клёна, в смысле CLENA ?
И что такое POL ?


 
Nikolay M. ©   (2005-07-25 09:56) [20]


> Deniz ©   (25.07.05 06:35) [18]
> Johnmen ©   (25.07.05 09:15) [19]

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


 
Johnmen ©   (2005-07-25 10:08) [21]

>Nikolay M. ©   (25.07.05 09:56) [20]

Будет сортировать. Так, как автору и надо, сначала девочки, потом мальчики. Если есть желание не уступать девочкам, то существует ASCENDING/DESCENDING.
На этом можно поставить точку.


 
sniknik ©   (2005-07-25 10:20) [22]

точку поставили еще в serguncho ©   (23.07.05 19:11) [15]
дальще пошол словоблуд... (тоже ничего себе занятие ;)
а автору надо не сортировать сначала девочки, потом мальчики, а TOP из 2 мальчиков и TOP двух девочек... сортировка здесь это только средство выбрать "крайних".
разница всетаки есть, выбирать сначала из М после из Ж (первых попавшихся если нет сортировки) и после сортировать, либо отсортировать каждый и выбирать по паре с максимальным рейтингом (даже если у Ж рейтинг в 3 раза ниже/выше чем у М. все одно по паре).


 
Nikolay M. ©   (2005-07-25 10:21) [23]


> Johnmen ©   (25.07.05 10:08) [21]

Блин. Ему не надо сначала девочки, а потом мальчики. Ему надо 2 топовых девочки и 2 топовых мальчика.
Оба запроса из [18] вернут по две случайных (грубо говоря) записи, т.к. в запросах не указан порядок сортировки. И только потом эти 4 записи отсортируются по полу и рейтингу. В общем случае они не будут самыми рейтинговыми.


 
Johnmen ©   (2005-07-25 10:34) [24]

Ну словоблуд, так и ладно...


 
Nikolay M. ©   (2005-07-25 10:43) [25]


> Johnmen ©   (25.07.05 10:34) [24]

Обиделся? :)


 
Johnmen ©   (2005-07-25 11:01) [26]


> Nikolay M. ©   (25.07.05 10:43) [25]


Конечно обиделся, на себя. :^)


 
Nikolay M. ©   (2005-07-25 11:04) [27]


> Johnmen ©   (25.07.05 11:01) [26]

Продыши, а то можно язву желудка заработать :)


 
Deniz ©   (2005-07-25 12:21) [28]

Согласен, фигню спорол, но для повышения производительности запроса, предлагаю к [14] добавить
SELECT first 2 * FROM TABLICA WHERE ID IN (select first 2 ID from TABLICA where POL_CLENA="m" ORDER BY 7 desc)
union
SELECT first 2 * FROM TABLICA WHERE ID IN (select first 2 ID from TABLICA where POL_CLENA="f" ORDER BY 7 desc)
вроде, как только найдется 2 мальчика, то первый запрос закончит свое выполнение, а не будет дальше перебирать оставшиеся записи, и соот-но с девочками


 
Deniz ©   (2005-07-25 12:22) [29]

... ну или ХП написать, там то все точно оптимизировать можно



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

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

Наверх





Память: 0.53 MB
Время: 0.013 c
2-1081121430
ChiNick
2004-04-05 03:30
2005.09.04
Как работать с цветом


4-1121342557
Kolan
2005-07-14 16:02
2005.09.04
Как установить RTS_CONTROL_TOGGLE. Работа с RS-485


2-1123267874
MAVr
2005-08-05 22:51
2005.09.04
Работа с папками…


14-1123438165
san4opan4o
2005-08-07 22:09
2005.09.04
Склад


14-1123576142
cspr
2005-08-09 12:29
2005.09.04
подключение 2-х компов с помощью розеток





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский