SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 01.04.2009 07:08:02

evgm
Участник
Зарегистрирован: 01.04.2009
Сообщений: 7

Прошу помочь с запросом

Привет всем!

Помогите, пожалуйста, составить запрос.
Нужно из табл выбрать записи, у которых равны значения в поле f1 И равны значения в поле f2 И не равны в поле f3
(поля все числовые)
то есть в результате запроса из таблицы

id f1 f2 f3
1 55 10 1
2 45 11 1
3 35 12 1
4 55 10 2
5 45 20 2
6 35 12 2
7 25 16 1
8 25 16 1

должны быть выбраны записи с id=1, id=4
id=3, id=6.
Никак не соображу как это сделать.
Сервер, если что, 6.0.3-alpha.

Заранее спасибо

Неактивен

 

#2 01.04.2009 08:32:19

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Прошу помочь с запросом

SELECT *
FROM tbl AS t1
JOIN tbl AS t2 USING(id)
WHERE t1.f1 = t2.f1 AND t1.f2 = t2.f2 AND t1.f3 != t2.f3

Неактивен

 

#3 01.04.2009 11:47:45

evgm
Участник
Зарегистрирован: 01.04.2009
Сообщений: 7

Re: Прошу помочь с запросом

что-то ничего не выбирает...

Неактивен

 

#4 01.04.2009 13:41:00

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Прошу помочь с запросом

Мне кажется, должно быть так:

Код:

SELECT t1.id, t2.id
FROM tbl as t1 JOIN tbl as t2 ON (t1.f1 = t2.f1 AND t1.f2 = t2.f2)
WHERE t1.f3 != t2.f3

LazY, если я правильно понимаю теорию, в твоем случае в результате объединения сначала построится строка
1 55 10 1 55 10 1
И условие t1.f3 != t2.f3 никогда не выполнится.

Отредактированно Magz (01.04.2009 13:44:32)

Неактивен

 

#5 01.04.2009 13:45:52

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Прошу помочь с запросом

Пардон, действительно USING(id) было лишним; да и выбирать надо было не просто *, а t1.* (не отошел еще от обдумывания одной из соседних тем)

Правильно, как Magz написал.

Неактивен

 

#6 01.04.2009 13:47:16

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Прошу помочь с запросом

Коллективный разум рулит smile

Неактивен

 

#7 01.04.2009 14:06:23

evgm
Участник
Зарегистрирован: 01.04.2009
Сообщений: 7

Re: Прошу помочь с запросом

Спасибо большое, все получилось!

Вы, конечно, догадываетесь, какой будет следующий вопрос...
А как сделать наоборот, выбрать то что осталось??? То есть выбрать записи, которые не попали в результат этого запроса.
И вообще, пожалуйста, подскажите, где почитать про JOIN, а то туговато я меня с ним что-то...

Спасибо.

Неактивен

 

#8 01.04.2009 16:12:38

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Прошу помочь с запросом

Первый способ "в лоб":

Код:

DELETE  t1, t2
FROM tbl as t1 JOIN tbl as t2 ON (t1.f1 = t2.f1 AND t1.f2 = t2.f2)
WHERE t1.f3 != t2.f3;

SELECT * FROM tbl;

big_smile roll

Второй способ "по лбу":

Код:

SELECT tbl.id FROM
tbl LEFT JOIN
(SELECT t1.id as t1_id, t2.id as t2_id
FROM tbl as t1 JOIN tbl as t2 ON (t1.f1 = t2.f1 AND t1.f2 = t2.f2)
WHERE t1.f3 != t2.f3) t3 ON (t3.t1_id = tbl.id OR t3.t2_id = tbl.id)
WHERE t3.t1_id is null AND t3.t2_id is NULL

Идея - сначала выбираем "ненужные" записи, а потом это множество объединяем с исходной таблицей. Берем те id для которых не нашлось соответствия при объединении. Вот только со скоростью, боюсь, будет хреново из-за OR в условии связки. Возможно, что лучше сделать два JOIN - отдельно с t1 и отдельно с t2. Предлагаю Вам подумать над этим самостоятельно, все данные есть. Выкладывайте результат размышлений сюда, если будут ошибки - подправлю. smile

Неактивен

 

#9 01.04.2009 16:14:54

Magz
Гуру
Откуда: Москва
Зарегистрирован: 18.09.2007
Сообщений: 112

Re: Прошу помочь с запросом

По-моему, я перемудрил в предыдущем посте.

Код:

SELECT t1.id, t2.id
FROM tbl as t1 JOIN tbl as t2 ON (t1.f3 = t2.f3)
WHERE t1.f1 != t2.f1 OR t1.f2 != t2.f2

Попробуйте оба - интересно, одинаковые результаты вернутся? smile

Неактивен

 

#10 02.04.2009 07:22:12

evgm
Участник
Зарегистрирован: 01.04.2009
Сообщений: 7

Re: Прошу помочь с запросом

Первый вариант работает правильно и быстро (табл на большая < 1000 записей)
Второй вариант возвращает неимоверно большое кол-во записей (раз в 500 больше чем записей в табл)
еще есть вариант:

SELECT * FROM tbl
WHERE id NOT IN (SELECT t1.id FROM tbl as t1
INNER JOIN tbl as t2 ON t2.f1 = t1.f1 AND
t2.f2 = t1.f2 AND t2.f3 != t1.f3);

результат правильный но выполняется раз в 10 медленнее (наверное из-за IN ???)
спасибо большое - буду использовать ваш первый вариант

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson