MYSQL使用group_concat获取搜索结果的计数

时间:2016-07-11 23:39:22

标签: mysql sql

好的,所以,我花了几个小时与我的伙伴一起解决这个问题。我采用了一种新的“层次结构”结构,这意味着“子”(商店)填写数据并抓取数据,或者它没有,因此父(链,所述商店的创建者)具有默认信息然后应该抓住它。 现在,我终于得到了这个搜索功能来处理这个事实。它在技术上工作得很好(虽然我猜它不是很有效,但SQL真的不是我的强项)

现在,我对此采取的问题是,在这个层次结构之前,我将结果总结为它所创造的匹配数量。 然而,因为我现在正在做很多'或者'或者'情况,那部分似乎变得混乱了。我尝试了很多东西(DISTINCT COUNTDISTINCT SUMCOUNTSUMTHEN 1THEN +1THEN -1等等。)

所以......是的......我真的被困在这个上面了。问题是,我需要计数器才能对相关性进行排序。

SELECT stores.ID, store_info.display_name, store_info.address, store_info.phone, 
       IFNULL(GROUP_CONCAT(DISTINCT smallCheese.display_name ORDER BY smallCheese.name),
              GROUP_CONCAT(DISTINCT bigCheese.display_name ORDER BY bigCheese.name)
) AS brands,
      IFNULL(GROUP_CONCAT( DISTINCT
      CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17)
      THEN smallCheese.display_name
      ELSE NULL
      END),
      (GROUP_CONCAT(DISTINCT
        CASE WHEN bigCheese.ID IN (3,5,8,11,12,13,14,16,17)
        THEN bigCheese.display_name
        ELSE NULL
        END))                  
       ) AS available_brands,
       COUNT(DISTINCT CASE WHEN smallCheese.ID OR bigCheese.ID IN (3,5,8,11,12,13,14,16,17)
             THEN 1
             ELSE 0
       END ) AS available_brands_count
    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 smallCheese ON store_brands.brand = smallCheese.ID
        LEFT JOIN brands AS bigCheese ON chain_brands.brand = bigCheese.ID
    WHERE stores.city = 1
    GROUP BY store_info.storeID  
        ORDER BY `available_brands_count`  DESC, store_info.display_name

这是一个SQL小提琴:http://sqlfiddle.com/#!9/cfe307/1/0

2 个答案:

答案 0 :(得分:1)

我认为这可行:

IF (MAX(CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17)
             THEN smallCheese.ID
             ELSE NULL
        END) IS NOT NULL,
    COUNT(DISTINCT
        CASE WHEN smallCheese.ID IN (3,5,8,11,12,13,14,16,17)
            THEN smallCheese.ID
            ELSE NULL
        END),
    COUNT(DISTINCT
        CASE WHEN bigCheese.ID IN (3,5,8,11,12,13,14,16,17)
            THEN bigCheese.ID
            ELSE NULL
        END)) AS available_brands_count

您不能只使用IFNULL(COUNT(...), COUNT(...)),因为如果没有匹配,COUNT()会返回0。我使用MAX()来汇总所有ID,如果找不到ID,则会返回NULL

DEMO

答案 1 :(得分:0)

我实际上改进了我的查询很多,非常感谢@Barmar提供的初始计数修复。因为它最终起作用,我实际上设法改进了查询!

SELECT stores.ID, store_info.display_name, store_info.address, store_info.phone, 
       IFNULL(GROUP_CONCAT(DISTINCT smallCheese.display_name ORDER BY smallCheese.name),
              GROUP_CONCAT(DISTINCT bigCheese.display_name ORDER BY bigCheese.name)
) AS brands,
      GROUP_CONCAT( DISTINCT
      CASE 
      WHEN smallCheese.ID IN (12,11,17) THEN smallCheese.display_name
      WHEN bigCheese.ID IN(12,11,17) AND smallCheese.ID IS NULL THEN bigCheese.display_name           
      ELSE NULL
      END ORDER BY bigCheese.name, smallCheese.name) AS available_brands,

      COUNT( DISTINCT
      CASE 
      WHEN smallCheese.ID IN (12,11,17) THEN smallCheese.display_name
      WHEN bigCheese.ID IN(12,11,17) AND smallCheese.ID IS NULL THEN bigCheese.display_name           
      ELSE NULL
      END) AS available_brands_count
    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 smallCheese ON store_brands.brand = smallCheese.ID
        LEFT JOIN brands AS bigCheese ON chain_brands.brand = bigCheese.ID
    WHERE stores.city = 1
    GROUP BY store_info.storeID  
        HAVING available_brands_count > 0
        ORDER BY `available_brands_count`  DESC, store_info.display_name