Задавайте вопросы, мы ответим
Вы не зашли.
Привет всем!
Помогите, пожалуйста, составить запрос.
Нужно из табл выбрать записи, у которых равны значения в поле 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.
Заранее спасибо
Неактивен
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
Неактивен
что-то ничего не выбирает...
Неактивен
Мне кажется, должно быть так:
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)
Неактивен
Пардон, действительно USING(id) было лишним; да и выбирать надо было не просто *, а t1.* (не отошел еще от обдумывания одной из соседних тем)
Правильно, как Magz написал.
Неактивен
Коллективный разум рулит
Неактивен
Спасибо большое, все получилось!
Вы, конечно, догадываетесь, какой будет следующий вопрос...
А как сделать наоборот, выбрать то что осталось??? То есть выбрать записи, которые не попали в результат этого запроса.
И вообще, пожалуйста, подскажите, где почитать про JOIN, а то туговато я меня с ним что-то...
Спасибо.
Неактивен
Первый способ "в лоб":
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;
Второй способ "по лбу":
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. Предлагаю Вам подумать над этим самостоятельно, все данные есть. Выкладывайте результат размышлений сюда, если будут ошибки - подправлю.
Неактивен
По-моему, я перемудрил в предыдущем посте.
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
Попробуйте оба - интересно, одинаковые результаты вернутся?
Неактивен
Первый вариант работает правильно и быстро (табл на большая < 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 ???)
спасибо большое - буду использовать ваш первый вариант
Неактивен