2017-03-22 45 views
0

我正在创建一个函数,该函数从标题为“序列”的表中返回一组记录。作为此表的一部分,我还在分析另一个表(“Log_Alpha”)并将适当的信息插入到记录中。到目前为止,我所做的是覆盖现有的列数据,然后在我选择调用该函数(IE SELECT * FROM Production1(parameters)as tbl(xxx,xxx,xxx,NewColumnName Real,xxx,xxx) ...)如何将新列添加到一组函数记录

这很好,但我需要保留原始数据,因此宁愿宁愿添加一个新的列到记录。但我该如何做,因为记录抓住了它的列名直接从

表“序列”我的代码显示RC。“seqLogsIn”是其中(平均每日SED)数据被捕获。这然后被从数据库中通过在看到SELECT查询称为列此代码的底部,其中列被重命名为“AvLogSED”

这里是完整的功能,但是您真的只需要关注SELECT AVG(“logSED”)部分。为了澄清,我想在记录中创建一个新列(称为AvLogSED,作为函数的一部分),并将数据注入到新列中,而不是“挪用”seqLogsIn。我怎么做?

我正在运行PostgreSQL 9.2.9,由Windows 7桌面PC上的Visual C++ build 1600,64位编译(本地服务器副本也在桌面上运行)。

-- Function: production1(timestamp without time zone, timestamp without time zone)  
-- DROP FUNCTION production1(timestamp without time zone, timestamp without time zone); 

CREATE OR REPLACE FUNCTION production1(tme1 timestamp without time zone, tme2 timestamp without time zone) 
    RETURNS SETOF record AS 
$BODY$ 
DECLARE 
    rc Record; 
    tmeA timestamp without time zone; 
    tmeB timestamp without time zone; 
    AverageSED Real; 

BEGIN 

tmeA := tme1 + '1 day'::interval; 
tmeB := tme2 + '1 day'::interval; 

-- get average SED for all logs in time/date range 
SELECT AVG("logSED")::Real 
    FROM "Log_Alpha" 
    WHERE "logTime" >= DATE_TRUNC('DAY', tme1) AND "logTime" < DATE_TRUNC('DAY', tme2 + '1 day'::interval) -- Calculate average for each day from 00:00 hours from first day thru to 23:59:59.99 for last day 
    INTO averageSED; 

    FOR rc IN 
    SELECT *, averageSED 
    FROM "Sequence" 
    WHERE "Sequence"."seqMinute" = 150 AND "Sequence"."seqTime" >= tmeA AND "Sequence"."seqTime" <= tmeB 
    ORDER BY "Sequence"."seqTime" 

    LOOP 
    rc."seqTime" = rc."seqTime" - '1 day'::interval; 

    -- Use a subquery to calculate the average SED for all logs for the day pertaining to this record date field 
    SELECT AVG("logSED")::Real into rc."seqLogsIn" FROM "Log_Alpha" -- Replace column seqLogsIn data from sequence table with Daily Average SED data. The column title can be renamed in function (SELECT) call as required 
     WHERE "Log_Alpha"."logTime" >= DATE_TRUNC('DAY', rc."seqTime") and "Log_Alpha"."logTime" < (DATE_TRUNC('DAY', rc."seqTime") + '1 day'::interval); -- Date truncated (always start at 00:00 hours of the day) to counter offset induced by mn variable 

    RETURN NEXT rc; 
    END LOOP; 
END 
$BODY$ 
    LANGUAGE plpgsql STABLE 
    COST 100 
    ROWS 1000; 
ALTER FUNCTION production1(timestamp without time zone, timestamp without time zone) 
    OWNER TO postgres; 

这是选择函数调用“重命名”将适当列AvLogSED。

select * from production1('2016-02-27 00:00:00','2016-03-11 00:00:00') as tbl(seqTime timestamp without time zone,seqMinute integer,AvLogSED Real,seqLogVolIn Real,seqFinishedVol Real,seqChipTonnes Real,seqSawdustTonnes Real,seqBinSortVol Real,seqTraySortVol Real,seqFlitchSortVol Real,seqBinSortPieces Real,seqTraySortPieces Real,seqFlitchSortPieces Real,seqBinSortRejects Real,seqBinSortSlash Real,seqTraySortRejects Real,seqTraySortSlash Real,seqCanterCants Real,seqSecBandCants Real,seqSecBandRecycled Real,seqCS1Cants Real,seqCS3Cants Real,seqE1Pieces Real,seqE1ManualRejects Real,seqE1OperatorRejects Real,seqE1ThicknessRejects Real,seqE1NoSortRejects Real,seqE1VolumeIn Real,seqE1VolumeOut Real,seqE2Pieces Real,seqE2ManualRejects Real,seqE2OperatorRejects Real,seqE2ThicknessRejects Real,seqE2NoSortRejects Real,seqE2VolumeIn Real,seqE2VolumeOut Real,seqE1Bypass Real,seqE2Bypass Real,seqBSVolumeIn Real,seqPrimaryRuntime Real,seqBinLugSpeed Real,seqBinLugFill Real,seqTrayLugSpeed Real,seqTrayLugFill Real,seqCompressor1kWh Real,seqCompressor2kWh Real,seqCompressor3kWh Real,seqCompressor4kWh Real,seqKiln1and2GJ Real,seqKiln3GJ Real,seqKiln4GJ Real,seqKiln5GJ Real,seqKiln6GJ Real,seqKiln7GJ Real,seqKiln8GJ Real,seqKiln9GJ Real,seqKiln10GJ Real,seqKiln11GJ Real,seqKiln12GJ Real,seqFlitchTray10 Real,seqFlitchReturn Real,seqBSLiftOut Real,seqSecCantRuntime Real,seqSecBandRuntime Real,seqSecCS1Runtime Real,seqSecCS3Runtime Real,seqEdger1Runtime Real,seqEdger2Runtime Real,seqBinSorterRuntime Real,seqTraySorterRuntime Real,seqFlitchSorterRuntime Real,seqReEntryE1Minutes Real,seqReEntryChipMinutes Real,seqAwaitingLogs Real,seqBSUtilisation Real,seqTSUtilisation Real,seqFSUtilisation Real,seqDebarkerRuntime Real,seqReEntryChipCount Real,seqReEntryE1Count Real,Reserved2 Real,Reserved3 Real,Reserved4 Real,Reserved5 Real,Reserved6 Real,AverageSED Real) 

回答

0

可以返回一个任意的记录是这样的:

RETURN NEXT ROW(val1, val2, ...); 

这样,你不被现有类型的限制。

+0

我已经试过了:[RETURN NEXT RC(seqTime时间戳没有时区,seqMinute整数,seqLogsIn真实,seqLogVolIn实...); ]但是我得到一个错误返回,指出错误处于或接近“(”。也尝试过使用和不使用数据类型 – witenitenz

+0

你应该*不*返回'rc(val1,val2,...)',这是一个语法错误,但'ROW(val1,val2,...)'。'ROW'是一个字面上的关键字。 –

0

该溶液被认为是如下:

FOR rc IN 
    SELECT *, AverageSED, avDailySED 
    FROM "Sequence" 
    WHERE "Sequence"."seqMinute" = mn AND "Sequence"."seqTime" >= tmeA AND "Sequence"."seqTime" <= tmeB 
    ORDER BY "Sequence"."seqTime" 
    LOOP 

通过添加AverageSED和avDailySED进行选择,这些柱自动添加到RC记录。我发现的一个问题是,我必须明确地将数据推送到记录rc中的avDailySED。通过这个我的意思是我现有的代码行:

SELECT AVG("logSED")::Real into avDailySED FROM "Log_Alpha" -- Store average SED value in new column 

会导致一个空白的avDailySED列。改变这一问题得到了解决:

SELECT AVG("logSED")::Real into rc.avDailySED FROM "Log_Alpha" -- Store average SED value in new column 
相关问题