最近,我们已经解释了SQL GROUP BY子句的句法含义。 如果您还没有,请阅读我们的文章“ 您真的了解SQL的GROUP BY和HAVING子句吗? ”。
本质上,在查询中添加GROUP BY
子句会在非常隐含的级别上转换查询。 以下提醒总结了上一篇文章:
- 只有
GROUP BY
子句中引用的列表达式或其他列表达式的集合可以出现在SELECT
子句中 - 没有显式
GROUP BY
子句的聚合意味着“总计”GROUP BY ()
子句 - 某些数据库( 例如MySQL ,在某种程度上:SQL标准)不遵循这些规则,并且在
SELECT
子句中允许使用任意列表达式(或至少在功能上依赖于列的表达式)
还有另一种查看GROUP BY
,它已经由Neo4j图形数据库支持的同样引人入胜,漂亮,怪异的Cypher查询语言 (那些是很好的属性)实现。 这种替代(但仍受SQL启发)查询语言可能值得单独撰写整个博客文章系列,但让我们关注聚合。 因为聚合是分组的主要用例。
- (有关记录,请查看Neo4j文档中有关聚合的详细信息)
快速总结以了解Cypher:
考虑以下简单的Cypher查询:
MATCH (me:Person)-->(friend:Person)
-->(friend_of_friend:Person)
WHERE me.name = 'A'
RETURN count(DISTINCT friend_of_friend),
count(friend_of_friend)
- 密码
MATCH
对应于SQLFROM
- Cypher
WHERE
…进行有根据的猜测 - Cypher
RETURN
对应于SQLSELECT
( 并且放在语义上更有用的位置 )
此外
- 暗号
(me:Person)-->(friend:Person) -->(friend_of_friend:Person)
大致对应于SQL
Person AS me JOIN Person AS friend ON [ implicit equi-join predicate ] JOIN Person as friend_of_friend ON [ implicit equi-join predicate ]
Cypher编写JOIN
的方式实际上非常有用,也可以应用于SQL。 直到有人编写实现该语法的Cypher-to-SQL转换程序只是时间问题,至少作为等效的ANSI等值连接表示法的语法糖。
让我们研究Cypher中的聚合
再次是查询:
MATCH (me:Person)-->(friend:Person)
-->(friend_of_friend:Person)
WHERE me.name = 'A'
RETURN count(DISTINCT friend_of_friend),
count(friend_of_friend)
因此,用SQL术语来说,这与以下内容完全相同:
SELECT count(DISTINCT friend_of_friend),
count(friend_of_friend)
FROM [ Persons ... ]
WHERE me.name = 'A'
换句话说,隐含相同的隐式总计GROUP BY ()
,并且所有值都汇总到单个行中。
Neo4j文档中的下一个示例更有趣。 这将计算连接到name = 'A'
的节点n
的节点数:
MATCH (n { name: 'A' })-->(x)
RETURN n, count(*)
这是一种较短的书写形式:
MATCH (n)-->(x)
WHERE n.name = 'A'
RETURN n, count(*)
此示例还将执行聚合,但是这次使用隐式GROUP BY n
子句。 在SQL中,您将编写如下内容:
SELECT n.id, count(*)
FROM n
JOIN x
ON [ implicit equi-join predicate ]
WHERE n.name = 'A'
GROUP BY n.id
Cypher中的GROUP BY n.id
是隐含了明显的GROUP BY
子句(只能是GROUP BY n.id
)。 它不必显式编写。
SQL外卖
我们已经看到了一些不错的Cypher语言功能,尤其是编写“ JOIN”(或者说Neo4j中的图形遍历)的一种非常好的方法。 但是,要使它成为SQL标准的一个更明显的,容易实现的结果是使SQL GROUP BY
子句成为可选的,并使用以下规则依赖于SELECT
子句:
- 如果
SELECT
包含聚合函数,则不应包含隐含的GROUP BY
子句 - 如果
SELECT
包含1-N个聚合函数,则其余的列应构成一个隐含的GROUP BY
子句 - 如果
SELECT
仅包含聚合函数,则应使用“总计”GROUP BY ()
- 一个明确的
GROUP BY
子句将始终优先于任何隐含的GROUP BY
子句
如果您有任何ISO / IEC委员会成员正在阅读此书,这是我希望用于将来的SQL标准的清单。 还有,PostgreSQL。 立即实施。
喜欢这篇文章吗?
这是有关SQL GROUP BY
子句和聚合的更多信息:
- Neo4j关于聚合的手册
- 如何将SQL GROUP BY和聚合转换为Java 8
- 您真的了解SQL的GROUP BY和HAVING子句吗?
- 按汇总分组/多维数据集
- 如何使用SQL PIVOT比较数据库中的两个表
- 很棒的PostgreSQL 9.4 / SQL:2003 FILTER子句,用于聚合函数
- 您还不知道的真正的SQL宝石:EVERY()聚合函数