2015-10-30 3 views
0

У меня есть стол products, artists и artist_product. Возможно, что продукт из нескольких художников, поэтому artist_product таблицы будет сказатьГруппировка с предложением where, где оба выражения должны быть правильными?

id = 1 
product_id = 1 
artist_id = 1 

id = 2 
product_id = 1 
artist_id = 2 

Что теперь я хочу иметь, чтобы получить все продукты, которые были изготовлены с помощью одних и тех же художников. Итак, все продукты, которые находятся как у Artist 1, так и у Artist 2, но не у кого-то другого (например, 3-й художник)

Предположим, у меня есть художник 1 и художник 2, как указано в приведенной выше таблице. Я ищу продукт с идентификатором 1. Теперь я хочу иметь все другие продукты, которые принадлежат тем же художникам (например, продукт 2, 3, 4 и т. Д.), Но не от других художников, а не от текущего продукта.

Я написал этот запрос

SELECT p.title, ap.product_id 
FROM artist_product ap 
INNER JOIN product p ON p.id = ap.product_id 
GROUP BY product_id 
HAVING COUNT(*) > 1; 

Теперь я получаю все продукты, которые имеют более одного художника, правильно? Но проблема в том, что теперь я получаю только продукты от нескольких художников, мне также нужно проверить художников. Я не могу сделать artist_id = x AND artist_id = x, потому что это не сработает из-за группы, и я также не могу сделать artist_id = x OR artist_id = x, потому что это будет не то же самое.

Мне нужно было решить эту проблему, а также нужно знать, как я разрешу это в Доктрине? У меня сейчас нет класса для ArtistProduct, мне нужно было бы создать его и сделать это вот так?

$qb = $em->getRepository('\namespace\Product')->createQueryBuilder('p'); 
$artists = $this->getArtists(); 
$qb->innerJoin('ap.artist_product', 'a', 'WITH', 'a.id IN (:artists)') 
    ->setParameter('artists', $this->getArtists()) 
    ->setMaxResults(12); 
$qb->andWhere('p.id != ' . $this->getId()); 
return $qb->getQuery()->getResult(); 

Это не выглядит правильным, должно быть что-то мне не хватает. Обычно я бы пошел и сначала создал запрос в SQL, а затем создал запрос в Doctrine, но я даже не получил запрос правильно.

ответ

1
SELECT p.id, p.title, ap2.product_id, count(*) c 
-- first select what we want - product 
FROM product p 
-- it must have both artists 
INNER JOIN artist_product ap 
    ON p.id = ap.product_id AND ap.artist_id IN (?, ?) 
-- catch any other artist 
LEFT JOIN artist_product ap2 
    ON p.id = ap2.product_id AND ap2.artist_id NOT IN (?, ?) 
GROUP BY p.id 
-- and exclude the product, if it has one 
HAVING ap2.product_id IS NULL 
-- there must also be exactly 2 artists 
AND c = 2; 
+0

Это выглядит многообещающе. Я просто заменяю вопросительные знаки идентификаторами художников в обоих случаях? Также в группе с помощью product_id является двусмысленным, следует ли использовать здесь 'ap' или' ap2'? Кроме того, в таблице 'artist_product' нет столбца' id', он просто существует из 'product_id' и' artist_id'. Я поддержал вас за усилия, если мы сможем решить оставшиеся вещи вместе, я соглашусь с – Musterknabe

+0

группой product_id, это ошибка, она должна быть p.id. Я также понимаю, что я не включил матч на 2 художника, обновленный. 1-й и 3-й? первый художник, 2-й и 4-й? второй идентификатор исполнителя. – Marek

+0

Похоже, что это будет работать, потрясающе! Возможно ли это с доктриной, или я должен использовать собственный запрос? – Musterknabe

Смежные вопросы