PostgreSQL使用select语句中的值作为同一语句中的变量

时间:2016-12-12 20:22:32

标签: sql postgresql

我的PostgreSQL数据库中有一个非常复杂的SQL语句,我在几个视图中用它作为基础。但是在这个语句中,sum聚合函数被多次调用。我现在正试图通过使用变量去除多次汇总这些值来优化这些视图。

我知道我可以使用@myvalue = 1,但这是在pgScript中,它不能在视图中使用,因为它是pgScript。

我已经阅读了关于滥用配置设置来存储变量的内容,但我不知道这是如何与视图一起播放的,而且我并不真的喜欢这样的黑客。

我希望存储在变量中的SQL部分是sum(v."Surface")::double precision,它会重复多次。

如果有任何其他建议可以优化此SQL,我会全力以赴。

CREATE OR REPLACE VIEW mydb."MyTable" AS 
SELECT p."Id",
    v."FunctionInt",
    v."TypeInt",
    sum(v."Surface") AS "SurfaceTotaal",
    round((sum(v."Surface"::double precision * v."Average") / sum(v."Surface")::double precision)::numeric, 1) AS "Average",
    round((sum(v."Surface"::double precision * v."E") / sum(v."Surface")::double precision)::numeric, 1) AS "E",
    round((sum(v."Surface"::double precision * v."E1") / sum(v."Surface")::double precision)::numeric, 1) AS "E1",
    round((sum(v."Surface"::double precision * v."E2") / sum(v."Surface")::double precision)::numeric, 1) AS "E2",
    round((sum(v."Surface"::double precision * v."E3") / sum(v."Surface")::double precision)::numeric, 1) AS "E3",
    round((sum(v."Surface"::double precision * v."M") / sum(v."Surface")::double precision)::numeric, 1) AS "M",
    round((sum(v."Surface"::double precision * v."M1") / sum(v."Surface")::double precision)::numeric, 1) AS "M1",
    round((sum(v."Surface"::double precision * v."M2") / sum(v."Surface")::double precision)::numeric, 1) AS "M2",
    round((sum(v."Surface"::double precision * v."M3") / sum(v."Surface")::double precision)::numeric, 1) AS "M3",
    round((sum(v."Surface"::double precision * v."G") / sum(v."Surface")::double precision)::numeric, 1) AS "G",
    round((sum(v."Surface"::double precision * v."G1") / sum(v."Surface")::double precision)::numeric, 1) AS "G1",
    round((sum(v."Surface"::double precision * v."G2") / sum(v."Surface")::double precision)::numeric, 1) AS "G2",
    round((sum(v."Surface"::double precision * v."G3") / sum(v."Surface")::double precision)::numeric, 1) AS "G3",
    round((sum(v."Surface"::double precision * v."G4") / sum(v."Surface")::double precision)::numeric, 1) AS "G4"
FROM mydb."PTable" p,
LATERAL ( 
    SELECT 
        v."Id",
        v."Surface",
        v."FunctionInt",
        v."TypeInt",
        r."YearGroupInt",
        r."Average",
        r."En" AS "E",
        r."En1" AS "E1",
        r."En2" AS "E2",
        r."En3" AS "E3",
        r."Mi" AS "M",
        r."Mi1" AS "M1",
        r."Mi2" AS "M2",
        r."Mi3" AS "M3",
        r."Gz" AS "G",
        r."Gz1" AS "G1",
        r."Gz2" AS "G2",
        r."Gz3" AS "G3",
        r."Gz4" AS "G4"
    FROM mydb."VTable" v
    JOIN mydb."RTable" r ON 
            v."FunctionInt" = r."FunctionInt" 
            AND v."TypeInt" = r."TypeInt" 
            AND v."YearGroupInt" = r."YearGroupInt"
    WHERE v."PId" = p."Id") v
GROUP BY p."Id", v."FunctionInt", v."TypeInt";

1 个答案:

答案 0 :(得分:1)

您假设多次计算CREATE TABLE foo AS SELECT * FROM generate_series(1,1E7) AS t; 是不正确的。规划师处理,自己测试。

EXPLAIN ANALYZE SELECT sum(t) FROM foo;

然后..

EXPLAIN ANALYZE SELECT sum(t), sum(t) FROM foo;

现在,尝试两个(没有明显的减速)

EXPLAIN ANALYZE SELECT sum(t), sum(t+0) FROM foo;

计划程序不会折叠常量,

 function shellFunction() {
  var sheets = ['Arabic', 'Portuguese', 'French','Spanish'];
  for (var s in sheets) {
    toTrigger(sheets[s]);
  }
}
  function toTrigger(sheetName) {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName(sheetName);
      var cell = ss.getActiveCell().getA1Notation();
      var row = sheet.getActiveRange().getRow();
      var cellvalue = ss.getActiveCell().getValue().toString();
      var recipients = sheet.getRange('J' + sheet.getActiveCell().getRowIndex()).getValue();
      var message = '';
      if (cell.indexOf('B') != -1)     
      {
        message = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue()
      }
      var subject = 'The ' + sheet.getRange('F' + sheet.getActiveCell().getRowIndex()).getValue() + ' ' + sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' needs your Translation';
      var body = sheet.getRange('A' + sheet.getActiveCell().getRowIndex()).getValue() + ' has been updated. Can you please update ' + sheet.getRange('G' + sheet.getActiveCell().getRowIndex()).getValue() + '? Please remember to update the date column in the Resource Document when the translation is complete:' + ss.getUrl();
      MailApp.sendEmail(recipients, subject, body);
  }