Помогите составить SQL запрос

NaN

Новичок
Помогите составить SQL запрос

Как вывести пользователей которые купили продукт product = '50' AND version = 'new',
но не покупили продукт product = '50' AND version = 'old'

CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL auto_increment,
`user` int(10) unsigned NOT NULL,
`product` int(10) unsigned NOT NULL,
`version` varchar(64) default NULL,
PRIMARY KEY (`id`),
KEY `user` (`user`),
KEY `product` (`product`)
) ENGINE=MyISAM;


INSERT INTO `products` VALUES (1, 5, 50, 'old');
INSERT INTO `products` VALUES (2, 5, 50, 'new');
INSERT INTO `products` VALUES (3, 6, 50, 'new');
 

Фанат

oncle terrible
Команда форума
А как ты писал? и при чем здесь эта таблица, если вывести надо пользователей?
 

NaN

Новичок
делал в таком стиле:

SELECT t1.user FROM `products` As t1 LEFT JOIN `products` As t2 ON t1.user = t2.user AND t1.product = '50'
WHERE t2.id IS NULL

и крутился вокруг да около но не выходит.
нужны эти пользователи, а так же их COUNT( t1.user )



P.S. жаль удалил старые темы в этом разделе, було кучу готовых решений и много чего обсуждали уже.

-~{}~ 25.05.09 17:32:

точнее такой делал запрос:
SELECT * FROM `products` As t1 LEFT JOIN `products` As t2
ON t1.user = t2.user AND t1.product = '50'
AND t1.varsion= 'new'
WHERE t2.id IS NULL
 

Фанат

oncle terrible
Команда форума
а откуда оно будет пустое?
и почему условие выборки находится в условии объединения?
 

NaN

Новичок
>а откуда оно будет пустое?
объединив две таблицы вывожу записи и теоретически t2 должна быть пустой, поэтому и пытаюсь писать t2.id IS NULL

>и почему условие выборки находится в условии объединения?
это один из вариантов моих попыток ( так писать можно, это по разному влияет на запрос )

-~{}~ 25.05.09 18:06:

хотя в документации на писано ( чёрным по белому ) что писать условия в ON нельзя
 

NaN

Новичок
хочется по умничать и сказать: - а как ты думаешь?
но я тут за помощью пришёл, поэтому, да я проверял
понимаю, что ты не просто так задаёшь мне все эти вопросы и после каждого из них я пробовал ещё несколько вариантов, да бы убедиться и не казаться глупым

вот собственно этот запрос, но к сожалению он нечего не выводит:

SELECT * FROM `products` As t1 LEFT JOIN `products` As t2
ON t1.user = t2.user
WHERE
t1.product = '50'
AND t1.varsion= 'new'
AND t2.id IS NULL
 

Фанат

oncle terrible
Команда форума
просто из products выборка делается?

стоп. что за тупизм? почему таблица джойнится к себе, а не к юзеру?
 

Farsh

~ on ~ high ~ wave ~
Автор оригинала: *****
стоп. что за тупизм? почему таблица джойнится к себе, а не к юзеру?
ему сейчас главное получить хотя бы ID юзеров

Nan Кстати, довольно интересная задачка, для меня ;) Попробую тоже сообразить

-~{}~ 25.05.09 21:02:

SELECT p.user, COUNT(c.user) AS count_old
FROM products p
LEFT JOIN products c ON p.user = c.user AND c.version = 'old'
GROUP BY p.user_id
HAVING count_old = 0
 

prolis

Новичок
метод с left join по-моему не проканает
[sql]
SELECT * FROM `products` t1
WHERE
t1.product = '50' AND t1.version= 'new'
AND user not in
(select user from products where product = '50' AND version= 'old')
[/sql]
кстати у тебя в запросе vArsion
 

brook73

Новичок
Метод предложенный самим ТС был верный - нужно действительно джойнить на себя. Метод с вложенным запросом поможет только при данном примере (с 2мя условиями). А если нужно будет найти все продукты которые также не 'special' и т.д.? Поэтому придётся джойнить на себя и накладывать условия на новые таблицы по порядку, причём число джойнов будет совпадать с числом условий.
 

prolis

Новичок
brook73 а ты приведи пример работающего запроса
там не получится, потому что у приджойненой таблицы должны выполниться два взаимоисключающих условия: "old" и "is null"
 

punchos

Новичок
вообщем смотри...тут тебе нужно использовать исключение множеств...ну или как там это называется из теории множеств...точно уж не помню...давненько дело было....за пересечение в сиквеле отвечает EXISTS, а за исключение соответсветнно NOT EXISTS....поэтому в твоем случае сработает запрос
select * from products as p where product=50 AND version = 'new'
AND not EXISTS
(SELECT id
FROM products
WHERE product=50 AND version = 'old' AND user = p.user);

-~{}~ 28.05.09 11:05:

вот...сделал добро и бросил его в воду....теперь хотелось бы чтоб добро мне добром же и вернулось...
есть такая проблема...

Предположим есть таблица людей
в ней хранятся ФИО, возраст, пол, номер паспорта(к примеру)
мне нужно делать поиск людей по комбинации 3 полей(ФИО, возраст, пол)
при чем делать следующий образом...
к примеру есть Иванов Иван Иваныч, 34(возраст), м(пол)
поиск осуществлять максимально избыточно
то есть, сейчас, я делаю 3 запроса: после каждого проверяю, если что то вернулось то поиск прекращается и два остальных запроса не осуществляются. Запросы:
1) по комбинации ФИО and Возраст and Пол
2) по комбинации ФИО and Возраст
3) по ФИО
я бы хотел не делать 3 запроса а запихнуть это все в один, с сортировкой по значимости....у кого какие мысли?
 

NaN

Новичок
спасибо всем за участие!
принял и запустил решение от prolis ( ошибся в слове version, спасибо! )

пробовал использовать идею punchos ( с EXISTS ) но, что-то с первого раза не получилась и я бросил :( но заметку в голове оставил, спасибо!

2punchos: насчёт вашего вопроса, я могу ошибаться, но попробуйте

( усолвие1 AND усолвие2 AND усолвие3 ) OR ( усолвие1 AND усолвие2 ) OR ( усолвие1 )
 

punchos

Новичок
NaN )))ну уж до этого я бы догадался

видимо не очень доступно описал проблему.....ну да ладно....уже сам все придумал...

NaN а то что с EXISTS у тебя не работает это действительно странно...и по логике работать должно...и на твоем примере проверял запрос, корректно отработал
 

NaN

Новичок
punchos - тоже хотелось помочь, поэтому написал, что знал,
ну если нашёл решение напиши, уверен комуто пригодится
 

punchos

Новичок
NaN Да мне не жалко...я бы написал...но дело в том что мое решение для очень специфичной задачи....долго ее объяснять бы пришлось
а то что описал это пытался локализовать проблему...но даже это вышло плохо....
вообщем уверен что ни кому это решение не пригодится
 
Сверху