4 таблицы запроса / соединения.получать дубликаты строк - PullRequest
2 голосов
/ 02 января 2011

Итак, я написал запрос, который будет захватывать заказ (для сайта типа электронной торговли), и из этого идентификатора заказа он получит все элементы заказа (ecom_order_items), параметры печати (c_print_options) и изображения (изображения). В настоящее время eoi_p_id является внешним ключом из таблицы изображений.

Это отлично работает, и запрос:

SELECT
eoi_parentid, eoi_p_id, eoi_po_id, eoi_quantity,
i_id, i_parentid,
po_name, po_price
FROM ecom_order_items, images, c_print_options WHERE eoi_parentid = '1' AND i_id = eoi_p_id AND po_id = eoi_po_id;

Вышеперечисленные вещи заберут все необходимое для заказа # 1

Теперь, чтобы усложнить ситуацию, я добавил дополнительную таблицу (ecom_products), которая должна действовать аналогично таблице изображений. Eoi_p_id также может указывать на внешний ключ в этой таблице. Я добавил дополнительное поле 'eoi_type', которое будет иметь значение 'image' или 'product'.

Теперь элементы в заказе могут состоять из набора элементов из изображений или ecom_products. Что бы я ни пытался сделать, либо получалось слишком много записей, на самом деле они не выводятся с eoi_type = 'product', а просто не работают. Любые идеи о том, как добиться того, что я после? Можете предоставить образцы SQL, если это необходимо?

SELECT
eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type,
i_id, i_parentid,
po_name, po_price, po_id,
ep_id
FROM ecom_order_items, images, c_print_options, ecom_products WHERE eoi_parentid = '9' AND i_id = eoi_p_id AND po_id = eoi_po_id

Приведенный выше вывод дублирует строки и не работает должным образом. Я поступаю об этом неправильно? Должны ли я иметь отдельные поля внешнего ключа для eoi_p_id, в зависимости от того, является ли оно изображением или продуктом?

Должен ли я использовать JOINs?

Вот mysql объяснение рассматриваемых таблиц

ecom_products

+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| ep_id       | int(8)       | NO   | PRI | NULL    | auto_increment |
| ep_title    | varchar(255) | NO   |     | NULL    |                |
| ep_link     | text         | NO   |     | NULL    |                |
| ep_desc     | text         | NO   |     | NULL    |                |
| ep_imgdrop  | text         | NO   |     | NULL    |                |
| ep_price    | decimal(6,2) | NO   |     | NULL    |                |
| ep_category | varchar(255) | NO   |     | NULL    |                |
| ep_hide     | tinyint(1)   | NO   |     | 0       |                |
| ep_featured | tinyint(1)   | NO   |     | 0       |                |
+-------------+--------------+------+-----+---------+----------------+

ecom_order_items

+--------------+-------------+------+-----+---------+----------------+
| Field        | Type        | Null | Key | Default | Extra          |
+--------------+-------------+------+-----+---------+----------------+
| eoi_id       | int(8)      | NO   | PRI | NULL    | auto_increment |
| eoi_parentid | int(8)      | NO   |     | NULL    |                |
| eoi_type     | varchar(32) | NO   |     | NULL    |                |
| eoi_p_id     | int(8)      | NO   |     | NULL    |                |
| eoi_po_id    | int(8)      | NO   |     | NULL    |                |
| eoi_quantity | int(4)      | NO   |     | NULL    |                |
+--------------+-------------+------+-----+---------+----------------+

c_print_options

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| po_id      | int(8)       | NO   | PRI | NULL    | auto_increment |
| po_name    | varchar(255) | NO   |     | NULL    |                |
| po_price   | decimal(6,2) | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

images

+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| i_id         | int(8)       | NO   | PRI | NULL    | auto_increment |
| i_filename   | varchar(255) | NO   |     | NULL    |                |
| i_data       | longtext     | NO   |     | NULL    |                |
| i_parentid   | int(8)       | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

Ответы [ 2 ]

2 голосов
/ 02 января 2011

Вам не хватает условия соединения для ecom_products в выражении WHERE или FROM. Вот как это можно сделать, используя соединения ANSI-92

SELECT
   eoi_id, 
   eoi_parentid, 
   eoi_p_id, 
   eoi_po_id, 
   eoi_po_id_2, 
   eoi_quantity, 
   eoi_type,
   i_id, 
   i_parentid,
   po_name, 
   po_price, 
   po_id,
   ep_id
FROM 
   ecom_order_items, 
   LEFT JOIN images
   ON i_id = eoi_p_id  
   LEFT JOIN c_print_options
   ON po_id = eoi_po_id 
   INNER JOIN ecom_products 
   ON eoi_p_id = ep_id
WHERE
   eoi_parentid = '9'  

Предпочтительны объединения ANSI 92, и немного понятнее, что такое объединение и что фильтрует. Тем не менее, вы можете просто добавить AND eoi_p_id = ep_id к вам, где пункт.

1 голос
/ 02 января 2011

Так я бы написал первый запрос. Я предпочитаю использовать соединения.

SELECT eoi_parentid, eoi_p_id, eoi_po_id, eoi_quantity, i_id, i_parentid, po_name, po_price
FROM ecom_order_items
INNER JOIN images
    ON i_id = eoi_p_id
INNER JOIN c_print_options 
    ON po_id = eoi_po_id
WHERE eoi_parentid = '1'

Для вашего второго запроса я бы использовал UNION для двух запросов, один для изображений и один для продуктов.

SELECT eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type, i_id, i_parentid, po_name, po_price, po_id, ep_id
FROM ecom_order_items
INNER JOIN images
    ON i_id = eoi_p_id
INNER JOIN c_print_options
    ON po_id = eoi_po_id
WHERE eoi_type = 'image' AND i_id = eoi_p_id --Image conditions
  AND eoi_parentid = '9'   
  AND po_id = eoi_po_id

UNION

SELECT eoi_id, eoi_parentid, eoi_p_id, eoi_po_id, eoi_po_id_2, eoi_quantity, eoi_type, i_id, i_parentid, po_name, po_price, po_id, ep_id
FROM ecom_order_items
INNER JOIN images
    ON i_id = eoi_p_id
INNER JOIN c_print_options
    ON po_id = eoi_po_id
WHERE eoi_type = 'product' AND ep_id = eoi_p_id -- Product conditions
  AND eoi_parentid = '9' 
  AND po_id = eoi_po_id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...