mysql 单个 table 组通过删除零元素

mysql single table group by removing zero elements

我有一个table如下

| ID |        CREATED       |                TITLE           |
| 1  |  07/09/2015 14:02:48 |  Render farm problem           |
| 2  |  06/16/2015 09:34:20 | Render server THSSE12 crashing |
| 3  |  05/16/2015 09:44:38 |  Patch to LG4 switch port 25   |

我希望能够计算 TITLE 字段中关键字的出现次数,例如按年和月渲染和格式化结果

| YEAR | MONTH | COUNT |
|2015  | 5     | 0     |
|2015  | 6     | 1     |
|2015  | 7     | 1     |

我尝试了几次内部联接,但没有任何乐趣,因为没有显示计数为 0 的月份。这是我所在的位置:-

 SELECT 
    CONCAT(YEAR(c.CREATED),MONTH(c.CREATED)) AS cdate,
    c.CREATED,
    COUNT(c.ID)
FROM 
    HD_TICKET AS c
LEFT JOIN 
    (SELECT
        CONCAT(YEAR(t.CREATED),MONTH(t.CREATED)) AS sdate,
        t.CREATED,
        COUNT(t.ID) AS tid
        FROM HD_TICKET t
        WHERE t.TITLE LIKE '%render%'
    ) AS t_count
ON c.CREATED = t_count.CREATED
GROUP BY YEAR(c.CREATED), MONTH(c.CREATED) 

非常感谢任何帮助!

未经测试,但我相信这会为您提供您所需要的。使用 SUM()CASE 表达式来计算子字符串的出现次数。

它使用了一个小技巧,即检查列的长度,将出现的子字符串替换为 0 个字符,并从原始字符串中减去新字符串的长度,然后将结果四舍五入并除以长度你的子串 :)

区分大小写:

select
  year(created) as year,
  month(created) as month,
  SUM(CASE WHEN title like '%render%' THEN round((length(title)-length(replace(title, 'render', '')))/length('render')) ELSE 0 END) AS count
from
  hd_ticket
group by
  year(created), month(created)

不区分大小写 lower():

select
  year(created) as year,
  month(created) as month,
  SUM(CASE WHEN lower(title) like lower('%reNder%') THEN round((length(title)-length(replace(lower(title), lower('reNder'), '')))/length('reNder')) ELSE 0 END) AS count
from
  hd_ticket
group by
  year(created), month(created);

Try it online on Rextester

不区分大小写的搜索将为您提供预期的输出。

| year | month | count |
+------+-------+-------+
|2015  | 5     | 0     |
|2015  | 6     | 1     |
|2015  | 7     | 1     |

这首先生成所有 years/months 值,然后左连接所需的数据。所有细节内联。如果愿意,您可以多年使用相同的技巧。 fiddle here

select  calendar.year_, calendar.month_, 
        coalesce(mydata.count_,0) as count_                    -- coalesce used to obtain 0 on missing data.
from
(   select y.year_, m.month_
    from
    (select distinct YEAR(CREATED) as year_ FROM hd_ticket) as y      -- all posible years
         ,                                                            -- comma here produces cross join
    (select 1 as month_ union all select 2                            -- all months 
     union all select 3 union all select 4
     union all select 5 union all select 6
     union all select 7 union all select 8
     union all select 9 union all select 10 
     union all select 11 union all select 12) as m
) as calendar                                                  -- a calendar: all years and all months
left join
(
    select count(*) as count_, year(CREATED) as year_, month(CREATED) as month_
    from HD_TICKET
    where TITLE like '%render%'
    group by year(CREATED), month(CREATED) 
) as mydata 
on calendar.year_ = mydata.year_ and calendar.month_ = mydata.month_
order by 1, 2