【问题标题】:use one table as a rule while performing select query on the other table使用一个表作为规则,同时对另一个表执行选择查询
【发布时间】:2016-06-29 06:14:24
【问题描述】:

我有一个表名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。

【问题讨论】:

  • 检查this answer。在你的情况下,它可能是select ct('select * from test', 'class_id', 'first_name || last_name', 'marks', 'ct_cur'); fetch all in ct_cur;

标签: postgresql


【解决方案1】:

所有学生?

有什么问题:

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

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

所以你有几个选择:

  1. 查看tablefunc 扩展并围绕crosstab() 函数动态生成查询
  2. 使用 xmljson 类型并返回对象或文档而不是记录。
  3. 使用我上面的查询和 excel 之类的客户端工具为您做交叉表。
  4. (编辑)您可以在存储过程中动态生成 SQL,并返回一个引用,但这会让您回到将“客户端”代码生成移动到函数中的问题。

编辑要明确你的问题是计划者的限制。您不能将列列表扩展为可变数量的列。所以你必须从数据库外部生成 SQL。 您不能直接在 SQL 中处理动态列数。

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

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

【讨论】:

  • 但是我想要的表格格式不一样。如上所述,我希望所有名称都出现在列中。所以请指导我编写查询来实现这一点。谢谢
  • 啊,所以你想要一个交叉表
  • 这可以在 CASE 语句的帮助下实现,无需进入交叉表。我已经为上述特定案例编写了相同的查询,但我希望在测试表的帮助下生成案例语句。最后一部分在循环的帮助下也提到了这一点。但是如何编写相同的查询是我所关心的......谢谢。
猜你喜欢
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-15
  • 2020-09-11
  • 1970-01-01
  • 2022-09-24
相关资源
最近更新 更多