Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [SQL&MySQL] Выбор предыдущих записей для указанных, категорий с сортировкой по дате. 
:(
    Опции темы
izOne
  Дата 30.10.2006, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: нет
Всего: 4



Связь вакансия-категории
Код

CREATE TABLE `vac_multi_cat` (
  `id` int(11) unsigned NOT NULL auto_increment,
  `cat_id` mediumint(9) unsigned NOT NULL,
  `vacancy_id` mediumint(9) unsigned NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `vc` (`cat_id`,`vacancy_id`),
  KEY `cat_id` (`cat_id`),
  KEY `vacancy_id` (`vacancy_id`),
  CONSTRAINT `vac_multi_cat_ibfk_1` FOREIGN KEY (`cat_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=cp1251 COMMENT='InnoDB free: 10240 kB; (`cat_id`) REFER `rabotaplus/categori';

Вакансии:
Код

CREATE TABLE `vacancy` (
  `id` mediumint(9) unsigned NOT NULL auto_increment,
  `isvip` tinyint(1) unsigned NOT NULL default '0',
  `user_id` mediumint(9) unsigned default NULL,
  `position` varchar(255) default NULL,
  `work_graph` tinyint(4) unsigned default NULL,
  `salary` smallint(6) unsigned default NULL,
  `experience` smallint(6) unsigned default NULL,
  `view_days` smallint(6) unsigned NOT NULL,
  `additional` text NOT NULL,
  `contact_email` varchar(40) default NULL,
  `city` varchar(30) default NULL,
  `address` varchar(255) default NULL,
  `phone` varchar(30) default NULL,
  `web_site` varchar(255) default NULL,
  `contact_person` varchar(100) default NULL,
  `add_date` datetime NOT NULL,
  `isactive` tinyint(1) unsigned NOT NULL default '0',
  `gender` tinyint(3) default NULL,
  `min_age` tinyint(3) default NULL,
  `max_age` tinyint(3) default NULL,
  `education` int(11) default NULL,
  PRIMARY KEY  (`id`),
  KEY `data_id` (`user_id`),
  KEY `isvip` (`isvip`),
  KEY `user_id` (`user_id`),
  KEY `salary` (`salary`),
  KEY `isactive` (`isactive`),
  KEY `id_isactive` (`id`,`isactive`),
  KEY `add_date` (`add_date`),
  FULLTEXT KEY `contact_email` (`contact_email`),
  FULLTEXT KEY `additional` (`additional`)
) ENGINE=MyISAM;


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

Пример: запрос
Код

SELECT * FROM (
    SELECT 
     `t1`.`cat_id`, `t1`.`vacancy_id`, `j1`.*, "prev" AS `navigation`
    FROM 
     `vac_multi_cat` AS `t1`
    INNER JOIN 
     `vacancy` AS `j1` ON (`j1`.`id`=`t1`.`vacancy_id`)
    WHERE 
     `t1`.`cat_id` IN ("291","363","385")
         AND
     `j1`.`add_date`<"2006-10-18 15:35:39"
    ORDER BY
     `j1`.`add_date` DESC
) AS `d1`

возвращает строки типа:
Код

cat_id    vacancy_id    id        isvip
385    276301        276301    0
291    413017        413017    0
385    172635        172635    0
385    412890        412890    0
385    412859        412859    0
385    397828        397828    0
291    339079        339079    0
363    666666        555555    0
...

Так вот из всего этого результата надо получить только 3 строки(запрашиваемая вакансия отнесена к 3 трем категориям, может относиться к любому кол-ву категорий)
Код

cat_id    vacancy_id    id        isvip
385    276301        276301    0
291    413017        413017    0
363    666666        555555    0


Это сообщение отредактировал(а) izOne - 30.10.2006, 13:19
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
sergejzr
Дата 30.10.2006, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 11
Всего: 360



из Форум программистов -> Программирование -> Базы данных -> MySQL


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Rodman
Дата 30.10.2006, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


CIO
****


Профиль
Группа: Участник
Сообщений: 6144
Регистрация: 7.5.2006
Где: Ukraine ⇛ Kyiv ci ty

Репутация: 26
Всего: 122



ну если тебе необходимо только 3 строки, то смотри
Код

SELECT ... LIMIT 3

PM MAIL WWW Skype GTalk YIM MSN   Вверх
izOne
Дата 30.10.2006, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: нет
Всего: 4



Rodman, 
Вобще то это понятно... ты посмотрел вопрос?
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
sergejzr
Дата 30.10.2006, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: 11
Всего: 360



Rodman, ты вопрос попытался понять, прежде чем отвечать?


izOne, это должно помочь
Код

SELECT * FROM (
    SELECT 
     distinct( `t1`.`cat_id`), `t1`.`vacancy_id`, `j1`.*, "prev" AS `navigation`
    FROM 
     `vac_multi_cat` AS `t1`
    INNER JOIN 
     `vacancy` AS `j1` ON (`j1`.`id`=`t1`.`vacancy_id`)
    WHERE 
     `t1`.`cat_id` IN ("291","363","385")
         AND
     `j1`.`add_date`<"2006-10-18 15:35:39"
GROUP BY `t1`.`cat_id`
   ORDER BY t1.cat_id
     `j1`.`add_date` DESC
) AS `d1`


Добавлено @ 13:39 
Модератор: Название темы должно отражать ее суть!


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Alexeis
Дата 30.10.2006, 13:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 23
Всего: 459



Цитата(izOne @  30.10.2006,  13:31 Найти цитируемый пост)
Вобще то это понятно... ты посмотрел вопрос? 

Модератор: правильно заданный вопрос залог быстрого и точного ответа.

Это сообщение отредактировал(а) alexeis1 - 30.10.2006, 13:42


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
izOne
Дата 30.10.2006, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: нет
Всего: 4



sergejzr, 
пробывал так... но distinct на айди категории ничего не дает да и в принципе не нужен(необходимо получить все вакансии в необходимых категориях, отсортировать их по дает добавления, и лишь потом получить три верхних с необходимыми категориями), а после группировки получаем не тот результат кот. хочется.
MySQL 5.

Добавлено @ 13:51 
alexeis1, 
Для того чтобы отвечать, необходимо читать вопрос!
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
izOne
Дата 30.10.2006, 14:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: нет
Всего: 4



sergejzr, 
Пробывал и нечто вот такое:
Код

SET @c_291 = 0;
SET @c_363 = 0;
SET @c_385 = 0;
SELECT * FROM (
    SELECT 
     `t1`.`cat_id`, `t1`.`vacancy_id`, `j1`.*, "prev" AS `navigation`, IF(`cat_id`=291, @c_291:=@c_291+1, IF(`cat_id`=363, @c_363:=@c_363+1, IF(`cat_id`=385, @c_385:=@c_385+1, 0))) AS `having_rule`
    FROM 
     `vac_multi_cat` AS `t1`
    INNER JOIN 
     `vacancy` AS `j1` ON (`j1`.`id`=`t1`.`vacancy_id`)
    WHERE 
     `t1`.`cat_id` IN ("291","363","385")
         AND
     `j1`.`add_date`<"2006-10-18 15:35:39"
    ORDER BY
     `j1`.`add_date` DESC
) AS `d1`
WHERE 
`d1`.`having_rule`=1

Но здесь загвоздка в том, что счетчики считают еще до сортировки и соответсвенно в результате неправильные данные.
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
muzer
Дата 30.10.2006, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 1
Всего: 31



Быстрого решения в общем-то нет.

Из работающих вариантов:
1.
Код

SELECT 
*
FROM
(
 SELECT
  tc.cat_id,MAX(tv.add_date) AS mdate
 FROM 
  vac_multi_cat tc 
 INNER JOIN 
  vacancy tv ON tv.id=tc.vacancy_id
 WHERE 
  tc.cat_id IN (291,363,385) 
 GROUP BY 
  cat_id
) cd
INNER JOIN
 vac_multi_cat c ON (c.cat_id=cd.cat_id)
INNER JOIN 
 vacancy v ON (v.id=c.vacancy_id AND v.add_date=cd.mdate) 
ORDER BY
 v.add_date


2.
Также можно воспользоваться решением, которое предлагается в документации mysql'я (но оно тоже тяжёлое, возможно тяжелее предыдущего, надо тестить):
Код

SELECT
 c.cat_id,LEFT(MAX(CONCAT(v.add_date+0,v.id)),14) AS date,SUBSTRING(MAX(CONCAT(v.add_date+0,v.id)),15) as v_id
FROM 
 vac_multi_cat c 
INNER JOIN 
 vacancy v ON v.id=c.vacancy_id
WHERE 
 c.cat_id IN (291,363,385) 
GROUP BY 
 cat_id


3. 
Тоже интересный, но тяжёлый вариант.

Код

SELECT
tmp1.*
FROM
(
 SELECT
  tc.cat_id,tv.add_date,tv.id
 FROM 
  vac_multi_cat tc
 INNER JOIN 
  vacancy tv ON tv.id=tc.vacancy_id
 WHERE 
  tc.cat_id IN (291,363,385) 
) tmp1
LEFT JOIN 
(
 SELECT
  tc.cat_id,tv.add_date,tv.id
 FROM 
  vac_multi_cat tc 
 INNER JOIN 
  vacancy tv ON tv.id=tc.vacancy_id
 WHERE 
  tc.cat_id IN (291,363,385) 
) tmp2 ON tmp2.cat_id=tmp1.cat_id AND tmp2.add_date > tmp1.add_date
WHERE 
 tmp2.id IS NULL


Список можно в принципе продолжить, но чего-то оптимальнее вряд ли можно найти..
Кстати, тоже потестите, возможно намного быстрее будет пользоваться вашим запросом, который возвращает все строки, а нужные отбирать уже в программе.

Добавлено @ 14:19 
sergejzr, судя по всему речь идёт про mysql, а там нет возможности указывать distinct только для одного поля. Или  строки уникальны по всем полям или не уникальны. Для уникальности по одному или неск полям, есть группировка (либо маленький изврат типа FORCE INDEX + ORDER BY, этот вариант не стал приводить, ибо это случайная фича mysql'я).
PM WWW   Вверх
izOne
Дата 30.10.2006, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 232
Регистрация: 22.8.2003
Где: Украина, Киев

Репутация: нет
Всего: 4



muzer, 
Спасибо, сейчас буду смотреть.
------
1. отработал как надо, и вроде бы не слишком долго(count(*) на InnoDb считался в десятки раз дольше)
2. неправильный результат: три строки, но отличаются только cat_id, два других столбца одинаковые.
3. результат аналогичен №2(одинаковые add_date и id для трёх строк) 

Это сообщение отредактировал(а) izOne - 30.10.2006, 14:59
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

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


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.0618 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.