MYSQL - 左加入双关系?

时间:2016-07-11 17:34:25

标签: mysql

    SELECT stores.ID, store_info.display_name, store_info.address,store_info.phone,
           IFNULL(
           GROUP_CONCAT(DISTINCT storeBrands.display_name ORDER BY storeBrands.name), 
           GROUP_CONCAT(chainBrands.display_name ORDER BY chainBrands.name)
          ) AS brands,
          IFNULL(
          GROUP_CONCAT(DISTINCT storeFilters.name ORDER BY storeFilters.name),
          GROUP_CONCAT(DISTINCT chainFilters.name ORDER BY chainFilters.name)
          ) AS filters
    FROM stores
      LEFT JOIN store_info ON stores.ID = store_info.storeID
      LEFT JOIN store_brands ON stores.ID = store_brands.store
      LEFT JOIN chain_brands ON stores.chainID = chain_brands.chain
      LEFT JOIN brands AS storeBrands ON store_brands.brand = storeBrands.ID
      LEFT JOIN brands AS chainBrands ON chain_brands.brand = chainBrands.ID
      LEFT JOIN store_filters ON  stores.ID = store_filters.store
      LEFT JOIN chain_filters ON stores.chainID = chain_filters.chain
      LEFT JOIN filters AS storeFilters ON store_filters.filter = storeFilters.ID
      LEFT JOIN filters AS chainFilters ON chain_filters.filter = chainFilters.ID
  WHERE stores.city = 1
  GROUP BY stores.ID

我已经更新了这个问题,因为我自己解决了最初的问题,但还有一个问题:

我该如何改进? 我觉得我已经取得了很多进步。我已经从使用子查询进行联合,到使用子查询进行单个查询,以改进我的连接,直到我不再需要为每一行执行子查询。

然而,它仍然感觉它会更好。我对自己的联盟​​非常不安全。 有人在这里有改进的提示吗?

目标: 我希望此查询从层次结构中获取结果。我们的“父母”(连锁店)与他们自己的孩子(商店)共享相同的品牌和过滤器(和其他东西)。这个想法是让'孩子'继承父母的设置作为后备,但在开始设置自己的数据时完全忽略它。 因此,基本上,对于一个查询,您需要“此数据或该数据”,而不是两者。非此即彼。 (UNION不适合的另一个原因)

2 个答案:

答案 0 :(得分:0)

如果您只想在商店没有链条时使用链条,请制定一个UNION。 UNION的一个操作数将主数据连接到存储数据,而另一个操作数 - 仅在存储没有时实例化 - 将主数据连接到链数据。这是人们使用UNION的原因:“我有时想要这些,我有时想要那些。”

答案 1 :(得分:0)

我自己设法解决了这个问题,也提高了效率,删除了大多数子查询!

SELECT stores.ID, store_info.display_name, store_info.address,store_info.phone,
       IFNULL(
         GROUP_CONCAT(DISTINCT storeBrands.display_name ORDER BY storeBrands.name), 
         GROUP_CONCAT(chainBrands.display_name ORDER BY chainBrands.name)
        ) AS brands,
        IFNULL(
          GROUP_CONCAT(DISTINCT storeFilters.name ORDER BY storeFilters.name),
          GROUP_CONCAT(DISTINCT chainFilters.name ORDER BY chainFilters.name)
        ) AS filters
 FROM stores
    LEFT JOIN store_info ON stores.ID = store_info.storeID
    LEFT JOIN store_brands ON stores.ID = store_brands.store
    LEFT JOIN chain_brands ON stores.chainID = chain_brands.chain
    LEFT JOIN brands AS storeBrands ON store_brands.brand = storeBrands.ID
    LEFT JOIN brands AS chainBrands ON chain_brands.brand = chainBrands.ID
    LEFT JOIN store_filters ON  stores.ID = store_filters.store
    LEFT JOIN chain_filters ON stores.chainID = chain_filters.chain
    LEFT JOIN filters AS storeFilters ON store_filters.filter = storeFilters.ID
    LEFT JOIN filters AS chainFilters ON chain_filters.filter = chainFilters.ID
WHERE stores.city = $cityID
GROUP BY stores.ID"