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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Не могу составить заппрос, выборка из двух таблиц c условием 
:(
    Опции темы
izOne
  Дата 9.2.2006, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Сильно прощенный вариант:

1-я таблица
oid date state
-----------------------------
1 2006-01-01 active
2 2006-01-01 hidden
3 2006-01-01 hidden
4 2006-01-01 deleted

2-я
oid pid string text integer
----------------------------------------------------------
1 2 стр3ка текст1 0
1 4 NULL NULL 45
2 2 с2тр5ка текст2 0
2 4 NULL NULL 60
3 2 стр текст3 0
3 4 NULL NULL 10
----------------------------------------------------------

Задача: выбрать из t1 строки в которых state = (active|hidden) причем для выбранных oid во второй таблице для pid=2 в колонке string должна встечаться строка "стр", а для pid=4 такого же oid - integer >= 20

Помогите пожалуйста.
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
Ignat
Дата 9.2.2006, 18:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Не проверял:
Код

SELECT `a`.`date`, `a`.`state`, `a`.`oid`, `b`.`pid`, `b`.`string`, `b`.`text`, `b`.`integer`
FROM `first_table` `a` INNER JOIN `second_table` `b` ON `a`.`oid`=`b`.`oid` 
WHERE (`a`. `state`='hidden' OR `a`. `state`='active') 
     AND (
                (`b`.`pid`=2 AND LOCATE('стр',`b`.`string`,0))
            OR 
                (`b`.`pid`=4 AND `b`.`integer`>=20)
             );



--------------------
Теперь при чем :P
PM   Вверх
izOne
Дата 9.2.2006, 19:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Ignat
с первой таблицы, в принципе все ясно, а вот со второй....
Код

                (`b`.`pid`=2 AND LOCATE('стр',`b`.`string`,0))
            OR 
                (`b`.`pid`=4 AND `b`.`integer`>=20)

мне кажеться(не проверял), что это накладывает условия или-или, а надо и-и. Причем если OR заменить на AND, то будет проверять текущая строка второй таблицы на соответствие двум условиям `pid`=2 AND `pid`= 4 - false, т.к. уникальный ключ на oid и pid второй таблицы...
Добавлено @ 19:10
Хм... а если сделать так:
Код

select `t1`.`oid`
from `t1`
inner join `t2` AS `j1` ON (`j1`.`oid`=`t1`.`oid` AND `j1`.`pid`=2 AND LOCATE('стр',`t1`.`string`,0))
inner join `t2` AS `j2` ON (`j2`.`oid`=`t1`.`oid` AND `j2`.`pid`=4 AND `j2`.`integer`>20)
WHERE (`t1`. `state`='hidden' OR `t1`. `state`='active')


то как сильно будет напрягаться сервер если `t2` будет INNER JOIN например 25 раз?
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
Ignat
Дата 9.2.2006, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



izOne, здесь предикаты для второй таблицы разбиты на две ветки, в каждой из них условие "И", т.к.pid не может быть одновременно 2 и 4, то связываем ветви логикой "ИЛИ".
Проверь, пожалуйста, если не работает, значит я тебя не понял.


--------------------
Теперь при чем :P
PM   Вверх
izOne
Дата 10.2.2006, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Вот такая тестовая табличка:
Код

CREATE TABLE `t1` (
  `oid` tinyint(3) unsigned NOT NULL auto_increment,
  `date` datetime NOT NULL default '0000-00-00 00:00:00',
  `state` enum('active','hidden','closed','deleted') default NULL,
  `title` varchar(255) default NULL,
  PRIMARY KEY  (`oid`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

INSERT INTO `t1` VALUES (1,'2006-02-01 00:00:00','active','Тест');
INSERT INTO `t1` VALUES (2,'2006-02-02 00:00:00','active','Еще название');
INSERT INTO `t1` VALUES (3,'2006-02-03 00:00:00','deleted','Удален');
INSERT INTO `t1` VALUES (4,'2006-02-04 00:00:00','hidden','Название');
INSERT INTO `t1` VALUES (5,'2006-02-05 00:00:00','active','Название');
DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2` (
  `oid` tinyint(3) unsigned NOT NULL default '0',
  `pid` tinyint(3) unsigned NOT NULL default '0',
  `string` varchar(255) default NULL,
  `text` text,
  `integer` int(11) default NULL,
  PRIMARY KEY  (`oid`,`pid`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

INSERT INTO `t2` VALUES (1,1,'bad',NULL,NULL);
INSERT INTO `t2` VALUES (1,2,NULL,NULL,10);
INSERT INTO `t2` VALUES (1,3,NULL,'ok',NULL);
INSERT INTO `t2` VALUES (2,1,'bad',NULL,NULL);
INSERT INTO `t2` VALUES (2,2,NULL,NULL,15);
INSERT INTO `t2` VALUES (2,3,NULL,'ok',NULL);
INSERT INTO `t2` VALUES (3,1,'ok',NULL,NULL);
INSERT INTO `t2` VALUES (3,2,NULL,'bad',20);
INSERT INTO `t2` VALUES (3,3,NULL,NULL,NULL);
INSERT INTO `t2` VALUES (4,1,'ok',NULL,NULL);
INSERT INTO `t2` VALUES (4,2,NULL,NULL,25);
INSERT INTO `t2` VALUES (4,3,NULL,'Bad',NULL);
INSERT INTO `t2` VALUES (5,1,'ok',NULL,NULL);
INSERT INTO `t2` VALUES (5,2,NULL,'',30);
INSERT INTO `t2` VALUES (5,3,NULL,'ok',NULL);


Такой запрос:
Код

SELECT * 
FROM `t1`
INNER JOIN `t2` AS `j1` ON (`j1`.`oid`=`t1`.`oid` AND (`j1`.`pid`=1  AND LOCATE('ok',`j1`.`string`))) /* 1,4,5 */
INNER JOIN `t2` AS `j2` ON (`j2`.`oid`=`t1`.`oid` AND (`j2`.`pid`=2  AND `j2`.`integer`>=15)) /* 4,5 */
INNER JOIN `t2` AS `j3` ON (`j3`.`oid`=`t1`.`oid` AND (`j3`.`pid`=3  AND LOCATE('ok',`j3`.`text`))) /* 5*/
WHERE `t1`.`state` IN ('active', 'hidden') /* 1,2,4,5 */


В результате остается только oid=5

Ignat
Код

SELECT *
FROM `t1` 
INNER JOIN `t2` AS `j1` ON `j1`.`oid`=`t1`.`oid` 
WHERE (`t1`.`state`='hidden' OR `t1`.`state`='active') 
     AND (
        (`j1`.`pid`=1 AND LOCATE('ok',`j1`.`string`))
            OR 
        (`j1`.`pid`=2 AND `j1`.`integer`>=15)
            OR 
        (`j1`.`pid`=3 AND LOCATE('ok',`j1`.`text`)
     )
);

Выдает 8 строк, т.е. не то что хотелось. Может я неправильно что-то сделал??? Хотелось бы, конечно, с минимальным количеством join'ов...
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
Ignat
Дата 10.2.2006, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Цитата(izOne @ 10.2.2006, 14:26 Найти цитируемый пост)

Выдает 8 строк, т.е. не то что хотелось.

А какие строки он должен выбрать, если говорить о тестовой табличке. На мой взгляд выбирается все, что нужно.


--------------------
Теперь при чем :P
PM   Вверх
izOne
Дата 10.2.2006, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Ignat
Должна быть одна строка с oid=5 кот. удовлетворяет всем условиям.
Добавлено @ 15:33
а так в результате есть, например, oid=1 у которго
1. integer < 15 (pid=2)
2. string = 'bad' (pid=1)
--------------------
Успех ждет каждого, но иногда всю жизнь.
PM Jabber   Вверх
Ignat
Дата 10.2.2006, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Флудератор
****


Профиль
Группа: Экс. модератор
Сообщений: 4030
Регистрация: 19.4.2004
Где: غيليندزيك مدينة

Репутация: 21
Всего: 73



Теперь я понял, что надо.


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


 




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


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

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