我有一个neo4j数据库,它有近500k CK_ITEM
个节点,定义如下:
CK_ITEM: {
id (String),
name (String),
description (String)
}
假设我们有这样的样本数据:
+--------+----+-----------------+
| name | id | description |
+--------+----+-----------------+
| Mark | 1 | A lot of things |
| Gerald | 9 | Coff2e |
| Carl | 2 | 1 mango |
| James | 3 | 5 lemons |
| Edward | 4 | Coffee |
+--------+----+-----------------+
我需要按description ASC
订购数据。这是我的问题:
MATCH (n:CK_ITEM)
ORDER BY
n.description ASC
这导致:
+--------+----+-----------------+
| name | id | description |
+--------+----+-----------------+
| Carl | 2 | 1 mango | <-- '1' < '5'
| James | 3 | 5 lemons | <-- '5' < 'A'
| Mark | 1 | A lot of things | <-- 'A' < 'C'
| Gerald | 9 | Coff2e | <-- '2' < 'e'
| Edward | 4 | Coffee |
+--------+----+-----------------+
现在,客户要求我订购结果,以便它们仍按升序排列,但数字是最后的。
基本上他希望结果如下:
+--------+----+-----------------+
| name | id | description |
+--------+----+-----------------+
| Mark | 1 | A lot of things |
| Edward | 4 | Coffee |
| Gerald | 9 | Coff2e | <-- Coff2e after Coffee
| Carl | 2 | 1 mango | <-- 1 and 5 ASC after everything
| James | 3 | 5 lemons |
+--------+----+-----------------+
转换为伪查询,它将是这样的:
MATCH CK_ITEM ORDER BY letters(description) ASC numbers(description) ASC
是否可以在单个查询中进行此类排序(字母优先升序,数字最后升序)?怎么样?
答案 0 :(得分:1)
以下是Cypher查询,它将执行数字排在最后的排序(在每个字符位置)。
注意:这种方法并不高效,但如果您绝对需要,可以作为如何在Cypher中执行此操作的示例。
查询将每个description
值拆分为单字符字符串,测试每个字符以查看它是否为数字,构造一个新字符串(逐个字符) - 用相应的UTF-16替换每个数字十六进制范围FFF6
到FFFF
中的字符(这些是最高可能的UTF-16字符编码,并且您的原始数据不太可能已经使用它们),并使用该新字符串进行排序。
WITH {`0`:'\uFFF6',`1`:'\uFFF7',`2`:'\uFFF8',`3`:'\uFFF9',`4`:'\uFFFA',`5`:'\uFFFB',`6`:'\uFFFC',`7`:'\uFFFD',`8`:'\uFFFE',`9`:'\uFFFF'} AS big
MATCH (n:CK_ITEM)
WITH n, SPLIT(n.description, '') AS chars, big
RETURN n
ORDER BY
REDUCE(s='', i IN RANGE(0, LENGTH(chars)-1) |
CASE WHEN '9' >= chars[i] >= '0'
THEN s + big[chars[i]]
ELSE s + chars[i]
END)
答案 1 :(得分:0)
您可以这样订购:
MATCH (n:CK_ITEM)
RETURN n
ORDER BY
substring(n.description,0,1) in ['0','1','2','3','4','5','6','7','8','9'], n.name
答案 2 :(得分:0)
您可以使用reqular表达式和UNION:
MATCH (n:CK_ITEM) WHERE NOT n.description =~ '[0-9].*'
RETURN n
ORDER BY
n.description ASC
UNION
MATCH (n:CK_ITEM) WHERE n.description =~ '[0-9].*'
RETURN n
ORDER BY
n.description ASC