【发布时间】:2014-08-16 11:24:12
【问题描述】:
在我们公司的 Netezza 机器上使用一些 SQL 查询,我试图将多个值连接到一个字符串中。问题是我需要对这些值进行排序,但 Netezza 不允许我按未分组的术语进行排序,因为它会在进行分组后应用排序。
我正在使用一个名为 group_concat 的 UDA,它连接字符串并在它们之间添加分隔符。我很确定 UDA 运行正常(在对其进行调整使其内部不进行任何排序之后)。
这是我的测试数据:
CREATE TABLE TEST (GRP INTEGER, ID INTEGER, DATA VARCHAR(10));
INSERT INTO TEST VALUES (1,3,"Three");
INSERT INTO TEST VALUES (1,1,"One");
INSERT INTO TEST VALUES (1,2,"Two");
INSERT INTO TEST VALUES (2,3,"Three");
INSERT INTO TEST VALUES (2,2,"Two");
INSERT INTO TEST VALUES (2,1,"One");
我想要以下输出:
- GRP:1,ConcatData:“一、二、三”
- GRP:2,ConcatData:“一、二、三”
这是我想做的事情:
SELECT GRP, GROUP_CONCAT(DATA)
FROM TEST
ORDER BY ID
GROUP BY GRP;
但这是不可能的:语法错误,因为 group by 必须在 order by 之前,并且在执行该 order by 之后只能应用于结果集中出现的术语。
其他人建议使用子选择来解决这个问题:子查询中的顺序和外部查询中的分组,如下所示:
SELECT GRP, GROUP_CONCAT(DATA,',') AS CONCATDATA
FROM
(
SELECT *
FROM TEST
ORDER BY GRP, ID
) AS X
GROUP BY GRP;
这似乎在 PostgreSQL 9.3 中有效,但在 Netezza 中无效。每次运行查询时,结果的顺序都会发生变化。
最后一个查询的问题与 group by 无关。外部选择忽略了内部选择的顺序,如下面的 sn-p 所示:
SELECT *
FROM
(
SELECT *
FROM TEST
ORDER BY GRP, ID
) AS X;
内部选择按预期对结果进行排序,但外部选择会任意重新排序(据我所知)。
所以我的问题是:
- 为什么 Netezza 会忽略我的结果排序?
- 如何构建一串分组但有序的数据?
PS:我应该如何在我的问题中包含和格式化结果集?我看不到如何制作表格。
编辑:在@Alex 的评论之后,我已经明确表示我想聚合一列(数据)中的值,但按另一列(id)排序。
编辑:我意识到 Netezza 可能无法以与其他一些数据库引擎相同的方式订购事物,因为数据是并行分布和处理的。 Netezza UDF 开发人员指南解释说,在 UDA 中,每个 SPU 首先聚合其拥有的数据,然后集中合并来自每个 SPU 的数据。在一个简单的 UDA 中,比如我看过的那些,合并函数不知道数据应该是什么顺序,即使数据是在每个 SPU 上排序的,也不能保证最终聚合的数据是有序的。也许有一种方法可以编写一个接受 ORDER BY 子句的 UDA……或者,我可以编写一个接受两个参数的 UDA,第一个是要聚合的字符串,第二个是顺序,但是,我不知道可以轻松地使用 UDA 中的关联数组。
编辑:Niederee's solution 有效,所以我接受了它,但我最终在 PostgreSQL 中创建了字符串,因为在加载到 Netezza 之前我们已经有一个 PostgreSQL 预处理阶段。仅供参考,这是将顶点坐标列表转换为可在 Netezza Spatial Toolkit(类似于 PostGIS)中使用的WKT string。
【问题讨论】: