Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Выборка по 30 неиндексированным полям 
:(
    Опции темы
Aliance
Дата 11.1.2007, 00:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



И для показа и для поиска, в том-то и дело.
PM MAIL WWW ICQ Skype   Вверх
Aliance
Дата 11.1.2007, 02:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Делаю такой запрос:
Код

SELECT * FROM `encyclopedia_dungeon_items` LEFT JOIN `dungeon_items` ON `encyclopedia_dungeon_items`.`ditem_id` = `dungeon_items`.`id` WHERE `encyclopedia_dungeon_items`.`item_id` = 654

Он мне возвращает 2 ряда:
"654";"3";"8";"3";"Кора Змеиного Дерева";"mater10";"1.00";"1";"0/1"
"654";"18";"1";"18";"Эссенция Глубины";"mater21";"1.00";"1";"0/1"

Из них я могу увидеть, какие ингридиенты и в каком количетсве нужны для покупки вещи с id 654 (в данном случае это 3 предметов с id 3 и 1 предмет с id 18). Гуд. Как дальше построить запрос поиска тех людей, у кого оба этих предмета присуствуют в количестве равном или большем, чем необходимо - не знаю. Если б с 1 предметом - легко, таким запросом:
Код

SELECT * FROM `members_dungeon_items` WHERE `item_id` = 3 AND `quantity` >= 8

Он выведет всех, у кого предмет с id 3 есть в количестве больше или равно 8. Но проблема в том, что для покупки предмета с id 654 мне нужно 2 предмета (id 3 и 18), а этим запросом я узнаю только про 1 предмет.
Тоесть нужно убьединить запросы
Код

SELECT * FROM `members_dungeon_items` WHERE `item_id` = 3 AND `quantity` >= 8
-- и
SELECT * FROM `members_dungeon_items` WHERE `item_id` = 18 AND `quantity` >= 1

И выбрать все уникальные member_id. Как? Дамп нужной части таблиц кинуть?

Помогите пожалуйса, сам не справляюсь.
PM MAIL WWW ICQ Skype   Вверх
Mal Hack
Дата 11.1.2007, 02:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Цитата(Aliance @  11.1.2007,  00:47 Найти цитируемый пост)
И для показа и для поиска, в том-то и дело. 

А поиска по самому mater или по mater им количеству одновременно?
PM ICQ   Вверх
Aliance
Дата 11.1.2007, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Цитата(Mal Hack @  11.1.2007,  03:59 Найти цитируемый пост)
А поиска по самому mater или по mater им количеству одновременно? 

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

PM MAIL WWW ICQ Skype   Вверх
Mal Hack
Дата 11.1.2007, 03:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Делаешь так. Одно поле, как я сказал - сам через строку:

Цитата(Mal Hack @  10.1.2007,  21:31 Найти цитируемый пост)
1-5|2-4|30-1
первое число - meter, второе - кол-во. 


Делаешь еще одно поле, SET'ом, и закидываешь туда те mater'ы, что есть у предмета.
Цитата(Mal Hack @  10.1.2007,  20:36 Найти цитируемый пост)
Смотри есть таблица соответствий
mater1 - 1
mater2 - 2
...
mater3 - 3
Есть таблица с предметами (нож, копье). Есть поле maters в нем, для ножа - пустое множество, для копья множество {1,2}, для другого предмета - свое, т.е. указывается только то, что есть. 

Поиск ведешь по второму полю. Очень быстро и удобно.
Работаешь с первым полем, не забывая обновлять второе (если какой-ть mater добавляется или удаляется). Запрос совсем не сложный.
PM ICQ   Вверх
Aliance
Дата 11.1.2007, 03:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Mal Hack, не, мне не нравится. Я, во-первых, плохо понимаю такую структуру, а соотв. это считай все равно что пользоваться готовым скриптом. Чужое, не понятное. Ну а во-вторых, мне кажется слишком много гемора будет нести такое хранение (редактирование например).
Был бы признателен, если б вы мне помогли с тем, что уже у меня есть, потому как я это все сделал сам и понимаю. Просто знаних не хватает составить запросы и логику правильно.
PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 11.1.2007, 03:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

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



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

Вроде можно и так:
Код
SELECT DISTINCT member.id
FROM encyclopedia_dungeon_items AS eitems
   LEFT JOIN members_dungeon_items AS member
   ON eitems.ditem_id = member.item_id AND eitems.required_quantity <= member.quantity
WHERE eitems.item_id = 654;

Возвращает народ имеющих нужные компоненты в достаточном количестве. Если в ответе будут null, значит есть компоненты (добавь eitems.ditem_id что бы знать какие), которых ни у кого нет. DISTINCT нужен т.к. один member.id может иметь кучу ингридиентов из рецепта (если в рецепте используеться куча).

Или так если инфа из dungeon_items (окромя id) нужна:
Код
SELECT DISTINCT member.id /* что угодно из dungeon_items */
FROM encyclopedia_dungeon_items AS eitems
   LEFT JOIN dungeon_items AS ditems
      LEFT JOIN members_dungeon_items AS member
      ON ditems.id = member.item_id AND eitems.required_quantity <= member.quantity
   ON eitems.ditem_id = ditems.id
WHERE eitems.item_id = 654;


Возможно мускул будет ругаться на AS, также возможно 5ый может ругаться на второй запрос (там JOIN'ы вроде стали жёще, нельзя просто eitems.required_quantity <= member.quantity, попробуй).


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Aliance
Дата 11.1.2007, 03:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Sardar, опа, спасибо, уже ближе как мне кажется к истине.
Немного подправил запрос:
Код

SELECT * 
FROM encyclopedia_dungeon_items AS eitems
LEFT JOIN members_dungeon_items AS member ON eitems.ditem_id = member.item_id
AND eitems.quantity = member.quantity
WHERE eitems.item_id =654

Он мне вернул:
Цитата

"654";"3";"8";NULL;NULL;NULL
"654";"18";"1";"9";"18";"1"
"654";"18";"1";"34";"18";"1"
"654";"18";"1";"63";"18";"1"
"654";"18";"1";"151";"18";"1"


Вот структура таблиц:
Код

-- 
-- Структура таблицы `encyclopedia_dungeon_items`
-- 

CREATE TABLE `encyclopedia_dungeon_items` (
  `item_id` smallint(4) unsigned default NULL,
  `ditem_id` smallint(4) unsigned default NULL,
  `quantity` tinyint(3) unsigned default '0',
  KEY `item_id` (`item_id`,`ditem_id`)
) TYPE=MyISAM;

-- 
-- Дамп данных таблицы `encyclopedia_dungeon_items`
-- 

INSERT INTO `encyclopedia_dungeon_items` (`item_id`, `ditem_id`, `quantity`) VALUES (654, 18, 1),
(654, 3, 8);

Код

CREATE TABLE `dungeon_items` (
  `id` smallint(4) unsigned NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `link` varchar(50) NOT NULL default '',
  `cost` varchar(4) default '1.00',
  `weight` smallint(1) unsigned default '1',
  `durability` char(3) default '0/1',
  PRIMARY KEY  (`id`),
  KEY `link_index` (`link`)
) TYPE=MyISAM AUTO_INCREMENT=32 ;

-- 
-- Дамп данных таблицы `dungeon_items`
-- 

INSERT INTO `dungeon_items` (`id`, `name`, `link`, `cost`, `weight`, `durability`) VALUES (1, 'Кожа Общего Врага', 'mater11', '1.00', 1, '0/1'),
(2, 'Сталь', 'mater12', '1.00', 1, '0/1'),
(3, 'Кора Змеиного Дерева', 'mater10', '1.00', 1, '0/1'),
(4, 'Корень Змеиного Дерева', 'mater9', '1.00', 1, '0/1'),
(5, 'Троекорень', 'mater8', '1.00', 1, '0/1'),
(6, 'Шкура Пещерного Оленя', 'mater1', '1.00', 1, '0/1'),
(7, 'Золото', 'mater2', '1.00', 1, '0/1'),
(8, 'Серебро', 'mater3', '1.00', 1, '0/1'),
(9, 'Лучистое Серебро', 'mater4', '1.00', 1, '0/1'),
(10, 'Мифрил', 'mater5', '1.00', 1, '0/1'),
(11, 'Железное Дерево', 'mater6', '1.00', 1, '0/1'),
(12, 'Слиток Пустынной Руды', 'mater7', '1.00', 1, '0/1'),
(13, 'Кристалл Стабильности', 'mater26', '1.00', 1, '0/1'),
(14, 'Кристалл Голоса Предков', 'mater25', '1.00', 1, '0/1'),
(15, 'Стихиалия', 'mater24', '1.00', 1, '0/1'),
(16, 'Ралиэль', 'mater23', '1.00', 1, '0/1'),
(17, 'Эссенция Чистоты', 'mater22', '1.00', 1, '0/1'),
(18, 'Эссенция Глубины', 'mater21', '1.00', 1, '0/1'),
(19, 'Эссенция Лунного Света', 'mater20', '1.00', 1, '0/1'),
(20, 'Кристалл Времён', 'mater19', '1.00', 1, '0/1'),
(21, 'Тысячелетний Камень', 'mater18', '1.00', 1, '0/1'),
(22, 'Плод Змеиного Дерева', 'mater17', '1.00', 1, '0/1'),
(23, 'Глубинный Камень', 'mater16', '1.00', 1, '0/1'),
(24, 'Сгусток Астрала', 'mater15', '1.00', 1, '0/1'),
(25, 'Сгусток Эфира', 'mater14', '1.00', 1, '0/1'),
(26, 'Кристалл Тысячи Ответов', 'mater13', '1.00', 1, '0/1'),
(27, 'Камень Затаённого Солнца', 'mater27', '1.00', 1, '0/1'),
(28, 'Лучистый Рубин', 'mater28', '1.00', 1, '0/1'),
(29, 'Лучистый Топаз', 'mater29', '1.00', 1, '0/1'),
(30, 'Шёпот Гор', 'mater30', '1.00', 1, '0/1'),
(31, 'Эссенция Праведного Гнева', 'mater31', '1.00', 1, '0/1');

Код

-- 
-- Структура таблицы `encyclopedia`
-- 

CREATE TABLE `encyclopedia` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `cost` varchar(20) default NULL,
  `weight` varchar(20) default NULL,
  `durability` varchar(20) default NULL,
  `requires` longtext,
  `influence` longtext,
  `options` longtext,
  `speciality` longtext,
  `link` mediumtext NOT NULL,
  `import` enum('Y','N') default NULL,
  `align` varchar(20) default NULL,
  `ancient` enum('Y','N') default NULL,
  `artefact` enum('Y','N') default NULL,
  `section` varchar(100) default NULL,
  `second` enum('Y','N') default 'N',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM PACK_KEYS=0 AUTO_INCREMENT=655 ;

-- 
-- Дамп данных таблицы `encyclopedia`
-- 

INSERT INTO `encyclopedia` (`id`, `name`, `cost`, `weight`, `durability`, `requires`, `influence`, `options`, `speciality`, `link`, `import`, `align`, `ancient`, `artefact`, `section`, `second`) VALUES (654, 'Броня Злодеяний', '380', '40', '0/100', '&bull; Ловкость: 50\r\n<br />&bull; Интуиция: 40\r\n<br />&bull; Уровень: 9\r\n<br />&bull; Выносливость: 30\r\n<br />&bull; Сила: 25', '&bull; Мф. против критического удара (%): +55\r\n<br />&bull; Мф. критического удара (%): +50\r\n<br />&bull; Мф. увертывания (%): +60\r\n<br />&bull; Ловкость: +7\r\n<br />&bull; Интуиция: +3\r\n<br />&bull; Защита от магии: +65\r\n<br />&bull; Уровень жизни (HP): +54\r\n<br />&bull; Сила: +2\r\n<br />&bull; Броня корпуса: 12-44 (11+d33)', '&bull; Защита от урона: +75\r\n<br />&bull; Часть комплекта: <strong>Комплект Злодеяний</strong> [12]', NULL, 'armor108', 'N', NULL, 'N', 'N', 'armor', 'N');

Код

-- 
-- Структура таблицы `members_dungeon_items`
-- 

CREATE TABLE `members_dungeon_items` (
  `member_id` smallint(4) unsigned NOT NULL default '0',
  `item_id` smallint(4) unsigned NOT NULL default '0',
  `quantity` tinyint(3) unsigned NOT NULL default '0'
) TYPE=MyISAM;

-- 
-- Дамп данных таблицы `members_dungeon_items`
-- 

INSERT INTO `members_dungeon_items` (`member_id`, `item_id`, `quantity`) VALUES (1, 29, 1),
(151, 2, 19),
(151, 1, 40),
(1, 26, 3),
(1, 25, 3),
(1, 24, 3),
(1, 23, 4),
(1, 21, 1),
(1, 20, 4),
(1, 12, 2),
(1, 11, 2),
(1, 10, 4),
(1, 9, 1),
(1, 8, 2),
(1, 7, 3),
(1, 6, 1),
(1, 5, 1),
(1, 3, 3),
(1, 2, 2),
(1, 1, 4),
(9, 28, 4),
(9, 18, 1),
(9, 3, 13),
(34, 28, 3),
(34, 18, 1),
(34, 8, 7),
(34, 3, 5),
(63, 28, 1),
(63, 18, 1),
(63, 8, 5),
(63, 3, 2),
(8, 28, 2),
(8, 8, 3),
(52, 3, 2),
(52, 8, 2),
(7, 1, 1),
(7, 8, 1),
(12, 28, 2),
(12, 18, 2),
(12, 9, 6),
(12, 8, 6),
(151, 8, 13),
(151, 28, 4),

PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 11.1.2007, 03:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

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



Видать хорошую дурь принимает автор названий ингридиентов (похоже рандмно скрипт генерит по словарю)  smile 

Вроде всё правильно вывел, Вбей в селект: "member.id, eitems.*", да на quantity проверке поставь <=, это я опечатался, поправил, а ты уже успел использовать (реально пару минут стояло smile ).


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Aliance
Дата 11.1.2007, 04:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Цитата(Sardar @  11.1.2007,  04:51 Найти цитируемый пост)
member.id

такого быть не может, такое наверное member.member_id  smile 

Нет не то, смотри, он мне выдает что у 5 пользователей есть все ингридиенты, пользовательские id - 9, 151, 34, 63, 12
Цитата

"9";"654";"3";"8"
"151";"654";"3";"8"
"9";"654";"18";"1"
"34";"654";"18";"1"
"63";"654";"18";"1"
"12";"654";"18";"1"
"151";"654";"18";"1"

А на самом деле нужно чтобы были только 2 юзера - 9 и 151 ведь только у них есть оба предмета в нужном кол-ве!

Цитата(Sardar @  11.1.2007,  04:51 Найти цитируемый пост)
Видать хорошую дурь принимает автор названий ингридиентов (похоже рандмно скрипт генерит по словарю) 

 smile  smile  smile 
PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 11.1.2007, 04:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

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



Угу, мой первый запрос будет возвращать id всех людей, имеющих хотя бы один из компонентов в достаточном количестве.
Можно группировать и выфильтровывать народ не имеющих всех id с ингридиентами, правда их нужно в начале из рецепта выцепить. Т.е. два запроса:
Код

/** положит  в 'total' */
SELECT COUNT(*)
FROM encyclopedia_dungeon_items AS eitems
   INNER JOIN dungeon_items AS ditems
   ON eitems.ditem_id = ditems.id
WHERE eitems.item_id = 654;

/** собсно сам запрос */
SELECT member.*, eitems.*
FROM encyclopedia_dungeon_items AS eitems
   INNER JOIN members_dungeon_items AS member
   ON eitems.ditem_id = member.item_id AND eitems.quantity <= member.quantity
WHERE eitems.item_id =654
GROUP BY member.id
HAVING COUNT(eitems.ditem_id) = total;


В первом запросе INNER JOIN не нужен если у тебя битых ссылок нет (т.е. энциклопедия всегда ссылаеться на существующие компоненты). Если БД поддерживает вложенные запросы, то можно так:

Код
SELECT member.*, eitems.*
FROM encyclopedia_dungeon_items AS eitems
   INNER JOIN members_dungeon_items AS member
   ON eitems.ditem_id = member.item_id AND eitems.quantity <= member.quantity
WHERE eitems.item_id =654
GROUP BY member.id
HAVING COUNT(eitems.ditem_id) = (SELECT COUNT(*) FROM encyclopedia_dungeon_items AS eitems WHERE eitems.item_id = 654);


Это сообщение отредактировал(а) Sardar - 11.1.2007, 04:30


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Mal Hack
Дата 11.1.2007, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Мудрый...
****


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

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



Цитата(Aliance @  11.1.2007,  03:22 Найти цитируемый пост)
Mal Hack, не, мне не нравится. Я, во-первых, плохо понимаю такую структуру, а соотв. это считай все равно что пользоваться готовым скриптом. Чужое, не понятное. Ну а во-вторых, мне кажется слишком много гемора будет нести такое хранение (редактирование например).
Был бы признателен, если б вы мне помогли с тем, что уже у меня есть, потому как я это все сделал сам и понимаю. Просто знаних не хватает составить запросы и логику правильно. 

Ну и зря...
PM ICQ   Вверх
Aliance
Дата 11.1.2007, 14:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 3
Всего: 137



Sardar, первый запрос возвращает 2, как и должен. Второй - работает отлично! Спасибо огромное!

Кстати, третий вопрос возвращает:
Цитата

#1064 - You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT COUNT( * ) FROM encyclopedia_dungeon_items AS eitems WHE 


Хотя вроде мускул поддерживает вложенные запросы... У меня он 4ка.
PM MAIL WWW ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




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


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

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