在另一个表上执行select查询时,通常使用一个表

时间:2016-06-29 06:14:25

标签: postgresql

我有一个表名test

first       last
raj         kumar
raj        patel

此表中有数百行。

我有另一个名为class的表,其中包含test表中存在的所有名称及其每个主题的标记。

class_id    first_name   last_name   subject     marks
 1       raj           kumar       physics    70
 1       raj           kumar       chemistry  70
 1       raj           patel       physics    80
 1       raj           kumar       math       90
 1       raj           kumar       computer   80
 1       raj           patel       chemistry  90
 1       raj           patel       math       100
 2       raj           kumar       physics    70
 2       raj           kumar       chemistry  70
 2       raj           patel       physics    80
 2       raj           kumar       math       90
 2       raj           kumar       computer   80
 2       raj           patel       chemistry  90
 2       raj           patel       math       100

现在我想知道以下格式在test表格中出现的每个学生的总分数:。

class_id    raj.kumar    raj.patel
 1          310           270
 2           n             m

因此,生成的tbale中会有n个列数

对于这个特殊情况,我们可以写

 select class_id
    sum(case when first_name = 'raj' and last_name = 'Kumar' then marks else 0) as "raj.kumar",
    sum(case when first_name = 'raj' and last_name = 'patel' then marks else 0)as "raj.patel"
    from class 
    group by class_id

由于test表中存在未修复的学生人数。所以我不想在查询中硬编码名字和姓氏。 我想要这样的东西,能够计算出test桌上所有学生的分数。

 select class_id, 
    for(i = 0; i < test.size; i++)
     sum(case when first_name = i.first and last_name = i.last then marks else 0 ) as i.first|| '.' ||i.last,
    from class
    group class_id

如何为此编写查询或存储过程 提前谢谢。

我正在使用postgresql。

1 个答案:

答案 0 :(得分:0)

对所有学生?

有什么问题:

select class_id, first_name, last_name, sum(marks)
  from class
group by class_id, first_name, last_name;

所以你想要一个交叉表。这里的主要问题是规划人员在开始之前需要知道有多少列以及它们的类型。所以坏消息是没有直接的方法来做到这一点。

所以你有几个选择:

  1. 查看tablefunc扩展程序,并围绕crosstab()函数
  2. 动态生成查询
  3. 使用xmljson类型并返回对象或文档而不是记录。
  4. 使用上面的查询和excel等客户端工具为您执行交叉表。
  5. (编辑)您可以在存储过程中动态生成SQL,并返回一个refcursor,但这会让您回到将“客户端”代码生成移动到函数中的问题。
  6. 编辑要明确您的问题是规划者限制。您不能将列列表扩展为可变数量的列。所以你必须从数据库外部生成SQL。 您无法直接在SQL中处理动态数量的列。

    现在,我强烈建议使用tablefunc扩展中的crosstab()函数,因为这样可以在概念上简化结果。如果必须手动执行此操作(请不要),可以通过从另一个表中选择,在pl / perl或pl / pgsql中编写查询生成器,然后将pl / pgsql的EXECUTE用于游标。然后,您可以返回refcursor.这不太理想,因为客户端必须从返回的refcursor中FETCH

    所以你的第一点是决定你将在哪里生成将要运行的SQL代码。这会在数据库客户端吗?或者在动态SQL中(要求客户端FETCH行与运行函数分开)?