Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/86.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为两个字段创建两个数组,保持数组的排序顺序同步(无子查询)_Sql_Arrays_Postgresql_Sorting_Aggregate Functions - Fatal编程技术网

Sql 为两个字段创建两个数组,保持数组的排序顺序同步(无子查询)

Sql 为两个字段创建两个数组,保持数组的排序顺序同步(无子查询),sql,arrays,postgresql,sorting,aggregate-functions,Sql,Arrays,Postgresql,Sorting,Aggregate Functions,这个问题没有任何押韵或理由,我只是好奇人们会怎么做 平台:当我希望有一个SQL标准解决方案时,我的主要精力集中在PostgreSQL 8.4+。(我知道9.0+有一些数组排序功能。) 我知道下面的查询是错误的,但结果与我想要的结果相似;将两个字段联系起来的方法(对组的排序也应该对dt进行排序): 是否有一种简单的方法来绑定字段进行排序,而不使用子查询?也许构建一个数组,然后取消它?我所知道的唯一使其平坦化的方法是使用一个数组。以下是查询的外观: --We first need to create

这个问题没有任何押韵或理由,我只是好奇人们会怎么做

平台:当我希望有一个SQL标准解决方案时,我的主要精力集中在PostgreSQL 8.4+。(我知道9.0+有一些数组排序功能。)

我知道下面的查询是错误的,但结果与我想要的结果相似;将两个字段联系起来的方法(对
组的排序也应该对
dt
进行排序):


是否有一种简单的方法来绑定字段进行排序,而不使用子查询?也许构建一个数组,然后取消它?

我所知道的唯一使其平坦化的方法是使用一个数组。以下是查询的外观:

--We first need to create the order hierarchy to recurse properly
SELECT *, ROW_NUMBER() OVER(PARTITION BY id ORDER BY group) AS rownum
INTO TEMP TableToRecurse
FROM foo

WITH RECURSIVE FinalOutput (id, group, dt, rownum) AS
(
--Anchor row of recursion
SELECT id, group, dt, rownum
FROM TableToRecurse 
WHERE rownum = 1
UNION ALL 
--Recursion piece
SELECT tr.id, FinalOutput.group || ', ' || tr.group, 
    FinalOutput.dt || ', ' || tr.dt, tr.rownum
FROM TableToRecurse AS tr
    JOIN FinalOutput
        ON  FinalOutput.id = tr.id AND FinalOutput.rownum = tr.rownum +1
)
--Final output only showing the last row (Max)
--Which should have everything concatenated together
SELECT FinalOutput.id, FinalOutput.group, FinalOutput.dt
FROM FinalOutput 
    JOIN 
    (
        SELECT MAX(rownum) AS MaxRowNum, id
        FROM FinalOutput
        GROUP BY id
    ) AS MaxForEach
        ON FinalOutput.id = MaxForEach.id 
            AND FinalOutput.rownum = MaxForEach.MaxRowNum

我所知道的唯一能让它变得平坦的方法就是使用。以下是查询的外观:

--We first need to create the order hierarchy to recurse properly
SELECT *, ROW_NUMBER() OVER(PARTITION BY id ORDER BY group) AS rownum
INTO TEMP TableToRecurse
FROM foo

WITH RECURSIVE FinalOutput (id, group, dt, rownum) AS
(
--Anchor row of recursion
SELECT id, group, dt, rownum
FROM TableToRecurse 
WHERE rownum = 1
UNION ALL 
--Recursion piece
SELECT tr.id, FinalOutput.group || ', ' || tr.group, 
    FinalOutput.dt || ', ' || tr.dt, tr.rownum
FROM TableToRecurse AS tr
    JOIN FinalOutput
        ON  FinalOutput.id = tr.id AND FinalOutput.rownum = tr.rownum +1
)
--Final output only showing the last row (Max)
--Which should have everything concatenated together
SELECT FinalOutput.id, FinalOutput.group, FinalOutput.dt
FROM FinalOutput 
    JOIN 
    (
        SELECT MAX(rownum) AS MaxRowNum, id
        FROM FinalOutput
        GROUP BY id
    ) AS MaxForEach
        ON FinalOutput.id = MaxForEach.id 
            AND FinalOutput.rownum = MaxForEach.MaxRowNum
试试这个:

select id,
  array_agg(agroup order by agroup) as AGroup,
  array_agg(dt order by dt desc) as dt
from t
group by id
这应该适用于PostgreSQL 9.1+

尝试以下方法:

select id,
  array_agg(agroup order by agroup) as AGroup,
  array_agg(dt order by dt desc) as dt
from t
group by id

这应该适用于PostgreSQL 9.1+

我将您的列名
group
更改为
grp
,因为
group
在Postgres和每个SQL标准中都是一个名称,不应该用作标识符

我理解你的问题是这样的:

以相同的排序顺序对两个数组进行排序,以便相同的元素位置对应于两个数组中的同一行

使用子查询CTE并在聚合前对行排序

SELECT id, array_agg(grp) AS grp, array_agg(dt) AS dt
FROM  (
    SELECT *
    FROM   tbl
    ORDER  BY id, grp, dt
    ) x
GROUP  BY id;
这比使用单独的
array\u agg()
like(自PostgreSQL 9.0以来一直存在)更快。Mosty对你的问题也有不同的解释,并使用适当的工具进行解释

子查询中的排序依据是否安全?

聚合函数
array\u agg
json\u agg
,[…]以及 类似的用户定义聚合函数,产生有意义的 不同的结果值取决于输入值的顺序。 默认情况下,此顺序未指定,但可以由控制 在聚合调用中编写一个
orderby
子句,如中所示 部分或者,从 排序的子查询通常会工作。例如:

SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
请注意,如果外部查询级别包含 附加处理,例如联接,因为这可能导致 要在计算聚合之前对子查询的输出进行重新排序

是的,在这个例子中是安全的

无子查询 如果确实需要不带子查询的解决方案,可以:

SELECT id
     , array_agg(grp ORDER BY grp)
     , array_agg(dt  ORDER BY grp, dt)
FROM   tbl
GROUP  BY id;
请注意按grp、dt排序的
。除了断开连接并使排序顺序明确之外,我还按
dt
进行排序。不过,
grp
不需要

还有一种完全不同的方法可以做到这一点:

请注意(id)
上的
DISTINCT,而不仅仅是
DISTINCT
,它产生相同的结果,但执行速度要快一个数量级,因为我们不需要额外的排序


我运行了一些测试,这几乎和其他两个解决方案一样快。正如所料,子查询版本仍然是最快的。使用
EXPLAIN analysis
进行测试,亲自查看。

我将您的列名
group
更改为
grp
,因为
group
是Postgres和每个SQL标准中的一个名称,不应用作标识符

我理解你的问题是这样的:

以相同的排序顺序对两个数组进行排序,以便相同的元素位置对应于两个数组中的同一行

使用子查询CTE并在聚合前对行排序

SELECT id, array_agg(grp) AS grp, array_agg(dt) AS dt
FROM  (
    SELECT *
    FROM   tbl
    ORDER  BY id, grp, dt
    ) x
GROUP  BY id;
这比使用单独的
array\u agg()
like(自PostgreSQL 9.0以来一直存在)更快。Mosty对你的问题也有不同的解释,并使用适当的工具进行解释

子查询中的排序依据是否安全?

聚合函数
array\u agg
json\u agg
,[…]以及 类似的用户定义聚合函数,产生有意义的 不同的结果值取决于输入值的顺序。 默认情况下,此顺序未指定,但可以由控制 在聚合调用中编写一个
orderby
子句,如中所示 部分或者,从 排序的子查询通常会工作。例如:

SELECT xmlagg(x) FROM (SELECT x FROM test ORDER BY y DESC) AS tab;
请注意,如果外部查询级别包含 附加处理,例如联接,因为这可能导致 要在计算聚合之前对子查询的输出进行重新排序

是的,在这个例子中是安全的

无子查询 如果确实需要不带子查询的解决方案,可以:

SELECT id
     , array_agg(grp ORDER BY grp)
     , array_agg(dt  ORDER BY grp, dt)
FROM   tbl
GROUP  BY id;
请注意按grp、dt排序的
。除了断开连接并使排序顺序明确之外,我还按
dt
进行排序。不过,
grp
不需要

还有一种完全不同的方法可以做到这一点:

请注意(id)
上的
DISTINCT,而不仅仅是
DISTINCT
,它产生相同的结果,但执行速度要快一个数量级,因为我们不需要额外的排序


我运行了一些测试,这几乎和其他两个解决方案一样快。正如所料,子查询版本仍然是最快的。使用
EXPLAIN ANALYZE
进行测试,亲自查看。

非常有趣-我必须更详细地了解这一点。这不是有效的PostgreSQL语法。看起来它是针对SQL Server的?是的,我的背景是SQL Server,但我仔细检查了这是否可以在PostGreSQL中完成(请参阅我的链接)。我注意到临时表语法不同,但我认为现在应该修复它。否则,这有什么问题吗?是的,我看到有哈希标记时不是Postgres,但我认为两个数据库之间的递归结构是相同的。@JustinPihony: