MySQL присоединиться к той же таблице - PullRequest
2 голосов
/ 25 февраля 2011

У меня есть одна таблица (называемая промежуточной) со следующими соответствующими полями:

id (PRIMARY)
bundle_id (INT)
product (enum H,L,D)
bundle_code (enum 10,20)

Мне нужно найти bundle_id, где bundle_code равен 10, а затем извлечь любые другие записи с тем же bundle_id, где product = H, и до двух дополнительных записей с тем же bundle_id, где product! = H. Я пытаюсь сделать все это в одном запросе, возвращая по одной строке на bundle_id; поэтому у меня есть список bundle_ids, каждый из которых содержит каждый продукт и идентификатор, прикрепленный к этому bundle_id.

Лучшее, что я придумал, это:

SELECT e1.bundle_id AS b_id, e1.product AS prod, e1.id AS id, 
e2.bundle_id AS b2_id, e2.product AS prod2, e2.id AS id2,
e3.bundle_id AS b3_id, e3.product AS prod3, e3.id AS id3,
e4.bundle_id AS b4_id, e4.product AS prod4, e4.id AS id4,    
FROM `staging` AS e1
INNER JOIN `staging` AS e2 ON (e1.bundle_id = e2.bundle_id AND e1.id != e2.id)
INNER JOIN `staging` AS e3 ON (e2.bundle_id = e3.bundle_id AND e2.id != e3.id)
INNER JOIN `staging` AS e4 ON (e1.bundle_id = e4.bundle_id AND e3.id != e4.id)
WHERE e1.bundle_code = '10'
AND e2.bundle_code = '20'
AND e2.product = 'H'
AND e3.product != 'H'
AND e4.product != 'H'

Похоже, что это работает нормально, если есть четыре результата, но если есть три результата, то один набор данных является дубликатом (в данном случае это id 1691):

b_id    prod    id      b2_id   prod2   id2     b3_id   prod3   id3     b4_id   prod4   id4
208768  NULL    1691    208768  H       1692    208768  NULL    1691    208768  L       1693

Если я добавлю дополнительные предложения WHERE, чтобы попытаться предотвратить это, вместо этого он вернет ноль строк, поэтому я думаю, что мой синтаксис JOIN где-то отключен. Есть идеи?

1 Ответ

4 голосов
/ 25 февраля 2011
SELECT e1.bundle_id AS b_id, e1.product AS prod, e1.id AS id, 
e2.bundle_id AS b2_id, e2.product AS prod2, e2.id AS id2,
e3.bundle_id AS b3_id, e3.product AS prod3, e3.id AS id3,
e4.bundle_id AS b4_id, e4.product AS prod4, e4.id AS id4,    
FROM `staging` AS e1
INNER JOIN `staging` AS e2 ON (e1.bundle_id = e2.bundle_id AND e1.id != e2.id)
LEFT JOIN `staging` AS e3 ON (e1.bundle_id = e3.bundle_id AND e2.id != e3.id AND e3.id != e1.id AND e3.product != 'H')
LEFT JOIN `staging` AS e4 ON (e1.bundle_id = e4.bundle_id AND e3.id != e4.id AND e4.id != e2.id AND e4.id != e1.id AND e4.product != 'H')
WHERE e1.bundle_code = '10'
AND e2.bundle_code = '20'
AND e2.product = 'H';
...