SQL查询:连接导致重复三次结果

时间:2014-02-27 15:12:12

标签: mysql sql

程序使用mySQL的SQL(phpMyAdmin)& MySQL Workbench
技能等级无可言之 注意 / PREFIX /附带了我签约的18个月前编写的SQL。

你好,有 我正在尝试检索Country,CountryID&从我的SQL数据库中说明 不幸的是,当国家进入时,需要使用第二次连接(订单T5); CountryID&在(address_book T7)中说明。

据我所知,它可能是太多连接? (我有点困惑)。

引起问题的加入(我尝试过:内部,左侧,右侧连接):

left Join /*PREFIX*/address_book T7 On (T7.customers_id = T5.customers_id)

完整的FROM子句:

From /*PREFIX*/products T1
    Left Join /*PREFIX*/orders_products T2 On (T1.products_id = T2.products_id)
    Inner Join /*PREFIX*/orders T5 On (T5.orders_id = T2.orders_id)
    Inner Join /*PREFIX*/products_description T3 On (T1.products_id = T3.products_id)
    Inner Join /*PREFIX*/customers T6 On (T5.customers_id = T6.customers_id)
    **left Join /*PREFIX*/address_book T7 On (T7.customers_id = T5.customers_id)**
    Left Join /*PREFIX*/paypal P1 On (P1.order_id = T5.orders_id)
    Left Join /*PREFIX*/manufacturers T4 On (T1.manufacturers_id = T4.manufacturers_id)
    Where (T5.date_purchased >= 20120101) 
    And (T5.date_purchased <= 20140227) 
    And T5.orders_status = 1

查询包含所有商店订单信息

Select
-- Other store Query --

-- Customer Information --
    T5.customers_id As CID,
    T6.customers_firstname As CFirst,
    T6.customers_lastname As CLast,
    T5.customers_name As CName,
    T5.customers_email_address As CEmail,
    T5.customers_country As CCountry,

    -- Following 2 lines from the 'FROM'
    T7.entry_country_id As CCountryID,
    T7.entry_state As CState,

我知道它可以用一些整理,但我不仅仅是SQL的初学者,只是足以解决一些代码问题,并将它粘贴回来。

使用复制/创建声明

CREATE TABLE `address_book` (
  `address_book_id` int(11) NOT NULL AUTO_INCREMENT,
  `customers_id` int(11) NOT NULL DEFAULT '0',
  `entry_gender` char(1) NOT NULL DEFAULT '',
  `entry_company` varchar(64) DEFAULT NULL,
  `entry_firstname` varchar(32) NOT NULL DEFAULT '',
  `entry_lastname` varchar(32) NOT NULL DEFAULT '',
  `entry_street_address` varchar(64) NOT NULL DEFAULT '',
  `entry_suburb` varchar(32) DEFAULT NULL,
  `entry_postcode` varchar(10) NOT NULL DEFAULT '',
  `entry_city` varchar(32) NOT NULL DEFAULT '',
  `entry_state` varchar(32) DEFAULT NULL,
  `entry_country_id` int(11) NOT NULL DEFAULT '0',
  `entry_zone_id` int(11) NOT NULL DEFAULT '0',
  PRIMARY KEY (`address_book_id`),
  KEY `idx_address_book_customers_id_zen` (`customers_id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=2917 DEFAULT CHARSET=utf8;

2 个答案:

答案 0 :(得分:2)

客户可以拥有多个地址,这会导致结果倍增。您应该尝试阅读LEFT JOIN如何工作

答案 1 :(得分:1)

返回的行数不是“太多”连接的问题本身,它实际上是表中正在连接的行的基数的问题。

例如,如果customer可以只有一个或多个delivery,那么在customerdelivery之间进行联接的查询将返回“重复” “客户,对于任何有多个交付的客户。

根据您的解释,听起来好像客户可以(并且确实)在address_book中有多个关联的行,并且对该特定customers_id的仅address_book的查询将返回三行。 / p>

您观察到的行为完全是预期的。

基本上有两种方法可以避免返回“重复”。一种方法是使用DISTINCT关键字或GROUP BY子句指定折叠行。另一种通用方法是从多表中过滤行,以便不使用内联视图生成重复项,或者在某些情况下,使用SELECT列表中的相关子查询生成重复项。

例如,您可以使用连接到内联视图替换JOIN到地址簿,为每个customers_id获取单个address_book_id,然后将其连接到address_book表以从具有该ID的行中检索其他列

即,替换它:

left Join /*PREFIX*/address_book T7 On (T7.customers_id = T5.customers_id)

有这样的事情:

LEFT 
JOIN ( SELECT T9.customers_id
            , MAX(T9.address_book_id) AS max_address_book_id
         FROM /*PREFIX*/address_book T9
        GROUP BY T9.customers_id
     ) T8
  ON T8.customers_id = T6.customers_id
LEFT
JOIN /*PREFIX*/address_book T7
  ON T7.customers_id = T8.customers_id
 AND T7.address_book_id = T8.max_address_book_id