如何在Cypher查询中使用GROUP BY?

13

我想将一个SQL查询翻译成Cypher。请问,有没有办法在Cypher中进行GROUP BY操作?

    SELECT dt.d_year, 
           item.i_brand_id          brand_id, 
           item.i_brand             brand, 
           Sum(ss_ext_discount_amt) sum_agg 
    FROM   date_dim dt, 
   store_sales, 
   item 
    WHERE  dt.d_date_sk = store_sales.ss_sold_date_sk 
    AND store_sales.ss_item_sk = item.i_item_sk 
    AND item.i_manufact_id = 427 
    AND dt.d_moy = 11 
    GROUP  BY dt.d_year, 
      item.i_brand, 
      item.i_brand_id 
   ORDER  BY dt.d_year, 
      sum_agg DESC, 
      brand_id;

Cyper会隐含地执行分组操作;无需输入“group by”,只需要将您的列进行排序并包含聚合函数即可。 - Dave Bennett
1
我不知道,谢谢! - Hajer
这是Cypher参考表 => https://neo4j.com/docs/cypher-refcard/current/ - Tezra
2个回答

27
在Cypher中,所有聚合函数都会隐式进行GROUP BY操作。在WITH / RETURN语句中,任何不属于聚合的列都将成为GROUP BY键。
因此,例如在
MATCH (n:Person)
RETURN COUNT(n), n.name, n.age

计数器将计算所有名称和年龄相同的节点。如果我改为

MATCH (n:Person)
RETURN COUNT(n), n.name, MIN(n.age), MAX(n.age)

我将获取相同姓名的人数计数,以及该姓名的年龄范围。


1
提醒一下,我曾经看到过至少一个版本的Neo4j(不确定是哪个版本,大约是3.3)如果键在聚合函数之后,则无法正确聚合。因此,RETURN count(n), n.name, n.age 可能不会按预期工作。为了保险起见,建议使用 RETURN n.name, n.age, count(n) - jacob.mccrumb

2
只要你有一个有限的预测组(比如一个enum等),你就可以使用以下技术。
UNWIND RANGE (1, 10) AS i
WITH COLLECT({ Val: i % 3 }) AS Item
RETURN REDUCE (
    acc = {}, 
    x IN Item | acc {
            .*, 
            V0: CASE x.Val WHEN 0 THEN coalesce(acc.V0 + 1, 1) ELSE acc.V0 END,
            V1: CASE x.Val WHEN 1 THEN coalesce(acc.V1 + 1, 1) ELSE acc.V1 END,
            V2: CASE x.Val WHEN 2 THEN coalesce(acc.V2 + 1, 1) ELSE acc.V2 END 
        }) AS grouping

另一个选项是:

UNWIND RANGE(1,15) AS i
  WITH i % 4 AS mod, 1 AS unit
  RETURN DISTINCT mod, count(unit) as unit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接