首页 文章

4表查询/加入 . 获取重复的行

提问于
浏览
2

所以我写了一个查询,它将获取一个订单(这是一个电子商务类型的网站),并从该订单ID它将获得所有订单项(ecom_order_items),打印选项(c_print_options)和图像(图像) . eoi_p_id当前是images表中的外键 .

这工作正常,查询是:

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分配一个单独的外键字段,具体取决于它的图像或产品吗?

我应该使用JOIN吗?

这是有问题的表的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

    这是我写第一个查询的方式 . 我更喜欢使用连接 .

    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
    
  • 1

    您在WHERE或FROM子句中缺少ecom_products的连接条件 . 这是使用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连接是首选,它更清晰's a join and what'的过滤 . 那说你可以在你的where子句中添加 AND eoi_p_id = ep_id .

相关问题