简体   繁体   English

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

[英]MYSQL get count of search results with group_concat

Ok, so, I've spent some hours working out this query with a buddy of mine. 好的,所以,我花了几个小时与我的一个伙伴一起解决这个查询。 I've adopted a new 'hierarchical' structure which means either the 'child' (store) fills out the data and it grabs that, or it doesn't, so the parent (chain, creator of said store) has the default information which should then be grabbed. 我采用了新的“分层”结构,这意味着“子”(存储)会填充数据并捕获数据,否则不会,因此父(链,存储的创建者)具有默认信息然后应该抓住。 Now, I finally got this search function to work with this fact. 现在,我终于有了这个搜索功能来处理这个事实。 It's technically working perfectly fine (Although I guess it's not very efficiënt, but SQL really isn't my strong suit) 从技术上讲,它工作得很好(尽管我猜它不是很有效,但是SQL确实不是我的强项)

Now, the issue I take with this is, that before this hierarchical structure, I'd 'sum' the results up into how many matches it had made. 现在,我要解决的问题是,在采用这种层次结构之前,我会将结果“求和”到已进行的匹配数中。 However , because I am now doing a whole lot of 'either or' situations, that part seems to be getting confused. 但是 ,由于我现在正在做很多“要么”的情况,那部分似乎变得很混乱。 I've tried many things ( DISTINCT COUNT , DISTINCT SUM , COUNT , SUM , THEN 1 , THEN +1 , THEN -1 , etc.) 我已经尝试了很多事情( DISTINCT COUNTDISTINCT SUMCOUNTSUMTHEN 1THEN +1THEN -1等)

So... yeah... I'm really stuck on this one. 所以...是的...我真的很喜欢这个。 The thing is, I need the counter in order to sort on the relevance. 问题是,我需要计数器才能对相关性进行排序。

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

Here's an SQL fiddle: http://sqlfiddle.com/#!9/cfe307/1/0 这是一个SQL提琴: http ://sqlfiddle.com/#!9/ cfe307/1/0

I think this might work: 我认为这可能有效:

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

You can't just use IFNULL(COUNT(...), COUNT(...)) because COUNT() returns 0 if there are no matches. 您不能只使用IFNULL(COUNT(...), COUNT(...))因为如果没有匹配项,则COUNT()返回0 I use MAX() to aggregate all the IDs, and if no IDs are found this will return NULL . 我使用MAX()汇总所有ID,如果未找到ID,则将返回NULL

DEMO 演示

I actually improved my query a lot , with many thanks to the initial count fix provided by @Barmar. 实际上,我的查询得到了很大的改善,这要归功于@Barmar提供的初始计数修复。 Because it finally worked, I actually managed to improve the query! 因为它终于成功了,所以我实际上设法改善了查询!

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM