如何从sconsole表按月筛选Google Search Console新增关键词?
按月统计同一site_id下的新增GSC关键词
嘿,我来帮你搞定这个新增关键词统计的问题!之前查询返回零结果甚至报错,大概率是日期处理或者对比逻辑出了小问题,下面给你两种简便的实现方法,不用手动按月折腾~
方法一:自连接 + NOT EXISTS(逻辑直观,适合小数据集)
这个方法思路很直接:先把数据聚合到月份维度,再对比当月和上月的关键词,找出当月出现但上月没出现的记录。
假设你的sconsole表包含site_id、query、date字段(GSC API返回的数据一般是按天的),先写个CTE把数据按月分组,确保每个关键词在每个月份只留一条记录:
WITH monthly_data AS ( SELECT site_id, query, DATE_TRUNC('month', date) AS month_start FROM sconsole GROUP BY site_id, query, DATE_TRUNC('month', date) ) SELECT current.month_start AS 统计月份, current.site_id, current.query AS 新增关键词 FROM monthly_data current WHERE NOT EXISTS ( SELECT 1 FROM monthly_data prev WHERE prev.site_id = current.site_id AND prev.query = current.query AND prev.month_start = DATE_TRUNC('month', current.month_start - INTERVAL '1 month') ) ORDER BY 统计月份, site_id;
小提示:
用DATE_TRUNC('month', date)生成每个月的起始日期,再用INTERVAL '1 month'计算上月,能避免手动处理月份天数的坑(比如2月转1月、12月转次年1月)。
方法二:窗口函数标记首次出现月份(高效,适合大数据集)
如果你的数据量比较大,自连接可能会慢,这时候可以先找出每个关键词第一次出现的月份,直接筛选每个月的首次记录就是当月新增:
WITH keyword_first_appearance AS ( SELECT site_id, query, MIN(DATE_TRUNC('month', date)) AS 首次出现月份 FROM sconsole GROUP BY site_id, query ) SELECT 首次出现月份 AS 统计月份, site_id, query AS 新增关键词 FROM keyword_first_appearance ORDER BY 统计月份, site_id;
这个方法只需要一次聚合,性能比自连接好很多,而且逻辑同样清晰——首次出现的月份就是关键词的新增月份。
为啥之前的查询会返回零结果?
给你排查几个常见坑:
- 日期处理错误:比如用
EXTRACT(YEAR_MONTH FROM date)时格式不统一,或者上月日期计算错误(比如硬写-30 days,遇到2月就错了),用DATE_TRUNC+INTERVAL更可靠。 - 数据本身无新增:可以先查
monthly_data的结果,看看有没有同一个关键词在不同月份出现的记录,如果所有关键词都是只在一个月出现,那新增结果自然为零。 - site_id匹配问题:检查
site_id是否有大小写、空格或者格式差异,确保对比时是完全匹配的。
关于按月迭代的简便实现
上面两种方法都是批量处理所有月份,完全不需要手动按月循环。如果你确实需要按月迭代(比如要按月导出结果),可以用数据库的循环语句,但一般来说批量处理更高效。举个PostgreSQL的循环例子(仅作参考,优先推荐前面的批量方法):
DO $$ DECLARE current_month DATE := (SELECT MIN(DATE_TRUNC('month', date)) FROM sconsole); last_month DATE := (SELECT MAX(DATE_TRUNC('month', date)) FROM sconsole); BEGIN WHILE current_month <= last_month LOOP RAISE NOTICE '正在处理月份: %', current_month; -- 输出当前月份的新增关键词 SELECT site_id, query FROM sconsole s WHERE DATE_TRUNC('month', s.date) = current_month AND NOT EXISTS ( SELECT 1 FROM sconsole WHERE site_id = s.site_id AND query = s.query AND DATE_TRUNC('month', date) = current_month - INTERVAL '1 month' ) GROUP BY site_id, query; current_month := current_month + INTERVAL '1 month'; END LOOP; END $$;
内容的提问来源于stack exchange,提问作者Arun Panneerselvam




