2017-03-22 46 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 
相關問題