Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.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/Postgres-根据组中的行位置将每N行折叠为1_Sql_Postgresql - Fatal编程技术网

SQL/Postgres-根据组中的行位置将每N行折叠为1

SQL/Postgres-根据组中的行位置将每N行折叠为1,sql,postgresql,Sql,Postgresql,我有一组来自Postgres表的有序结果,其中每组4行表示一组相关数据。我想进一步处理这组结果,这样每一组4行都会被折叠成一行,列名称有别名,其中每一列的值都基于该行在组中的位置-我很接近,但我不能完全正确地进行查询(我也不相信我正在以最佳方式接近这一点)。以下是场景: 我正在收集调查结果-每个调查有4个问题,但每个答案都存储在数据库中的单独一行中。但是,它们通过提交事件\u id相互关联,并且结果保证以固定顺序返回。一组调查结果将类似于: event_id | answer --

我有一组来自Postgres表的有序结果,其中每组4行表示一组相关数据。我想进一步处理这组结果,这样每一组4行都会被折叠成一行,列名称有别名,其中每一列的值都基于该行在组中的位置-我很接近,但我不能完全正确地进行查询(我也不相信我正在以最佳方式接近这一点)。以下是场景:

我正在收集调查结果-每个调查有4个问题,但每个答案都存储在数据库中的单独一行中。但是,它们通过提交
事件\u id
相互关联,并且结果保证以固定顺序返回。一组
调查结果将类似于:

  event_id   |    answer
----------------------------
     a       |     10
     a       |     foo
     a       |     9
     a       |     bar
     b       |     2
     b       |     baz
     b       |     4
     b       |     zip
我想能够做的是查询这个结果,这样最终的输出会在它们自己的行中显示出每组4个结果,并带有别名的列名

event_id  |  score_1  |  reason_1  |  score_2  |  reason_2
----------------------------------------------------------
    a     |   10      |    foo     |     9     |    bar
    b     |   2       |    baz     |     4     |    zip
我能得到的最接近的是

SELECT survey_answers.event_id,
    (SELECT survey_answers.answer FROM survey_answers FETCH NEXT 1 ROWS ONLY) AS score_1,
    (SELECT survey_answers.answer FROM survey_answers OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY) AS reason_1
    (SELECT survey_answers.answer FROM survey_answers OFFSET 2 ROWS FETCH NEXT 1 ROWS ONLY) AS score_2,
    (SELECT survey_answers.answer FROM survey_answers OFFSET 3 ROWS FETCH NEXT 1 ROWS ONLY) AS reason_2
FROM survey_answers
GROUP BY survey_answers.event_id
但可以理解的是,这返回了正确的行数,但具有相同的值(除了
event\u id
):

如何构造查询,使其在每批4行中应用
偏移量
/
获取
行为,或者更准确地说,在每个唯一的
事件id集
s中应用行为?

首先,这看起来是一个非常糟糕的设计:

  • 没有保证的订单!数据库以随机顺序存储数据,并以随机顺序调用它们。您确实需要一个订单列。在这种小情况下,这可能适用于事故

  • 您应该生成两列,一列表示分数,一列表示原因。把这些类型混在一起不是个好主意

  • 不过,对于这个简单而简短的示例,这可能是一个解决方案(请记住,不建议将此用于生产表):

  • 行编号()为每个
    事件id
    添加行计数。在这种情况下,从1到4。这可用于识别回答的类型(参见FIDLE中的中间步骤)。在生产性代码中,您应该使用一些order列来确保顺序。然后,窗口函数看起来像是
    partitionbyevent\u id orderbyorder\u column
  • 这是一个关于
    事件id
    和类型id(行号)的简单轴心,它完全符合您的期望
  • 首先,这看起来是一个非常糟糕的设计:

  • 没有保证的订单!数据库以随机顺序存储数据,并以随机顺序调用它们。您确实需要一个订单列。在这种小情况下,这可能适用于事故

  • 您应该生成两列,一列表示分数,一列表示原因。把这些类型混在一起不是个好主意

  • 不过,对于这个简单而简短的示例,这可能是一个解决方案(请记住,不建议将此用于生产表):

  • 行编号()为每个
    事件id
    添加行计数。在这种情况下,从1到4。这可用于识别回答的类型(参见FIDLE中的中间步骤)。在生产性代码中,您应该使用一些order列来确保顺序。然后,窗口函数看起来像是
    partitionbyevent\u id orderbyorder\u column
  • 这是一个关于
    事件id
    和类型id(行号)的简单轴心,它完全符合您的期望

  • 您需要一个列来指定顺序。在您的情况下,这可能是一个
    serial
    列,它保证在每次插入时都会增加。我会把这样一个专栏称为“调查结果id”

    使用此列,您可以执行以下操作:

    select event_id,
           max(case when seqnum = 1 then answer end) as score_1,
           max(case when seqnum = 2 then answer end) as reason_1,
           max(case when seqnum = 3 then answer end) as score_2,
           max(case when seqnum = 4 then answer end) as reason_2
    from (select sr.*,
                 row_number() over (partition by event_id order by survey_result_id) as seqnum
          from survey_results sr
         ) sr
    group by event_id;
    

    如果没有这样一个列,您就无法可靠地执行所需的操作,因为SQL表表示无序集

    您需要一个列来指定顺序。在您的情况下,这可能是一个
    serial
    列,它保证在每次插入时都会增加。我会把这样一个专栏称为“调查结果id”

    使用此列,您可以执行以下操作:

    select event_id,
           max(case when seqnum = 1 then answer end) as score_1,
           max(case when seqnum = 2 then answer end) as reason_1,
           max(case when seqnum = 3 then answer end) as score_2,
           max(case when seqnum = 4 then answer end) as reason_2
    from (select sr.*,
                 row_number() over (partition by event_id order by survey_result_id) as seqnum
          from survey_results sr
         ) sr
    group by event_id;
    

    如果没有这样一个列,您就无法可靠地执行所需的操作,因为SQL表表示无序集

    在回答这个问题时,我们必须看到第三列,其中提供了
    事件id
    组中每个项目的顺序。@skwidbreth。“结果保证按固定顺序返回”。你不了解数据库或Postgres。表格表示无序的集合。唯一的排序方法是使用带有
    order by
    子句的列或表达式。如果没有包含订购信息的列,则无法执行所需操作。如果没有第三列提供
    事件\u id
    组中每个项目的订购信息,则无法回答此问题。@skwidbreth。“结果保证按固定顺序返回”。你不了解数据库或Postgres。表格表示无序的集合。唯一的排序方法是使用带有
    order by
    子句的列或表达式。如果您没有包含订购信息的列,则无法执行所需操作。谢谢,Gordon。你说得对,我对数据库/博士后的知识有限。这不是我设计的一个表/模式,只是一个我一直坚持的,试图充分利用它的表/模式。你实际上回答了我发布的一个相关问题,其中每个字段都有一个唯一的ID-这是我理想的处理此查询的方式,但不幸的是,这些身份证可能会随着时间的推移而改变,不能一直依赖……谢谢,戈登。你说得对,我对数据库/博士后的知识有限。这不是我设计的一个表/模式,只是一个我一直坚持的,试图充分利用它的表/模式。实际上,你已经回答了我发布的一个相关问题,其中每个字段都有一个唯一的ID——这是我理想的处理此查询的方式,但不幸的是,这些ID可能会随着时间的推移而变化,无法被考虑
    select event_id,
           max(case when seqnum = 1 then answer end) as score_1,
           max(case when seqnum = 2 then answer end) as reason_1,
           max(case when seqnum = 3 then answer end) as score_2,
           max(case when seqnum = 4 then answer end) as reason_2
    from (select sr.*,
                 row_number() over (partition by event_id order by survey_result_id) as seqnum
          from survey_results sr
         ) sr
    group by event_id;