自从把DBMS从Mysql换成PostgreSQL后,章郎虫在数据操作的时候老是会碰到问题。这不今天又碰到了一个很有意思的问题,弄了好久还是没有解决。最后找了高手,回家又看了下书,然后个人简单总结下和SQL童鞋们一起分享。不会SQL的孩子真的伤不起啊!
本来在Mysql中,使用以下sql语句不会出现任何问题:
注:这里需要把数据库稍微介绍下,match_code是根据title值计算出来的。
SELECT count(*) AS matchCount,a.title AS title,a.url AS url
FROM article_label al INNER JOIN article a ON al.aid=a.aid
WHERE al.lid=239 AND a.match_code IS NOT NULL AND a.tm_post BETWEEN ‘2011-07-17’ AND ‘2011-09-17’ AND a.style!=4
GROUP BY a.match_code
ORDER BY matchCount DESC
LIMIT 20 ;
但是使用PostgreSQL,还是上面这条sql,运行就碰到问题了。具体的错误提示信息是这样的:
Error: column “article.title” must appear in the GROUP BY clause or be used in an aggregate function。
看这个英文的意思就是需要将article.title这个字段加在group by的分组字段中。而如果你只是单纯的加上这个字段,运行后还是会报错。只是这个时候系统就提示你需要把article.url这个字段也加上。再加上后运行是正常了,但是得到的结果肯定是错误的了。
最后把上面这个sql修改成以下后就可以成功运行了:
SELECT count(*) AS matchCount,a.title AS title,max(a.url) AS url
FROM article_label al INNER JOIN article a ON al.aid=a.aid
WHERE al.lid=239 AND a.match_code IS NOT NULL AND a.tm_post BETWEEN ‘2011-07-17’ AND ‘2011-09-17’ AND a.style!=4
GROUP BY a.match_code,a.title
ORDER BY matchCount DESC
LIMIT 20 ;
因为match_code和title值成一一对应关系,所以可以简单的将title字段作为第二个(冗余的)分组字段。而title一样的文章中url会存在差别,所以这里随便选择了max(url)。
分组查询(GROUP BY)的限制:
以下是从书里抄来的,感觉一直说的很模糊,哈哈。
1、分组字段必须是在查询的FROM子句中命名的表的实际字段。对出现在分组查询的选择列表中的项也有一些限制,可以是:
a.一个字段(假设他是分组字段之一);
b.一个常量;
c.一个字段函数,此函数生成一个值,该值汇总组中的记录;
d.一个分组字段,按照定义,这个分组字段在组中的每一记录有同样的值;
f.涉及上述各项组合的表达式;
2、当分析分组查询的合法性时,SQL忽略关于主键和外键的信息。就像今天章郎虫碰到的问题,主要的错误就是title和url字段没有被明确地指定 为分组字段。