2016-07-08 26 views
0

一組或數組我的id在一個WHERE語句中的SET工會的功能形式,讓我有效季節性天爲某些類羣的ID是否有使用PostgreSQL中

WHERE 
... 
tx_id IN ('00020','00030','00059') AND 
datepart('doy',dt) IN (
    SELECT TAXA_SEASON(1,'00020') UNION 
    SELECT TAXA_SEASON(1,'00030') UNION 
    SELECT TAXA_SEASON(1,'00059')) 

和tax_sesion是一個函數我可以選擇4個季節。

CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURING TEXT) 
RETURNS SETOF INTEGER AS 
$BODY$ 
... 
$BODY$ 
LANGUAGE plpgsql; 

是否有使用在PostgreSQL

datepart('doy',dt) IN (SELECT TAXA_SEASION(1,{'00020','00030','00059'})) 
+0

在這種情況下,'IN'運算符應該如何工作,當一邊是集合的集合/結果集,另一邊是整數? –

+0

我試過使用僞語法..sorry – huckfinn

回答

1
CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURINGS TEXT[]) 
RETURNS SETOF INTEGER AS 
$BODY$ 
DECLARE 
    E TEXT; 
BEGIN 
    FOREACH E IN ARRAY EURINGS LOOP 
    RETURN QUERY SELECT TAXA_SEASON(SEAS, E); 
    END LOOP; 
    RETURN; 
END 
$BODY$ 
LANGUAGE plpgsql; 

用法的一組或數組聯合的功能形式:

WHERE 
... 
tx_id = ANY(ARRAY['00020','00030','00059']) AND 
datepart('doy',dt) IN (SELECT TAXA_SEASON(1,ARRAY['00020','00030','00059'])) 

UPD:這是「懶惰「的解決方案不需要對現有代碼進行更改。正確的解決方案是反轉的邏輯:

創建類似功能:

CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURING TEXT[]) 
RETURNS SETOF INTEGER AS 
$BODY$ 
    -- Get ready to use (distinct) data for all values from EURING 
$BODY$ 
LANGUAGE plpgsql; 

CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURING TEXT) 
RETURNS SETOF INTEGER AS 
$BODY$ 
    select taxa_season(SEAS, ARRAY[EURING]) 
$BODY$ 
LANGUAGE sql; -- Note that it is simple SQL function 

這將是更高的效率。

+0

謝謝!使用'SELECT DISTINCT TAXA_SEASON(1,ARRAY ['00020','00030','00059'])ORDER BY TAXA_SEASON;'我得到了預期的結果。 – huckfinn

+0

@huckfinn看看更新。 – Abelisto

0

感謝@Abelisto最終它幫助我出來,整個結構看起來像這樣..請求

-- -------------------------------------------------------- 
CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURING TEXT) 
RETURNS SETOF INTEGER AS 
$BODY$ 
...find some date limits in the taxa tables 
$BODY$ 
LANGUAGE plpgsql; 
-- -------------------------------------------------------- 
CREATE OR REPLACE FUNCTION taxa_season(SEAS INTEGER, EURINGS TEXT[]) 
RETURNS SETOF INTEGER AS 
$BODY$ 
DECLARE 
    E TEXT; 
BEGIN 
    FOREACH E IN ARRAY EURINGS LOOP 
    RETURN QUERY SELECT TAXA_SEASON(SEAS, E); 
    END LOOP; 
    RETURN; 
END 
$BODY$ 
LANGUAGE plpgsql; 
-- ---------------------------------------------- 
CREATE OR REPLACE FUNCTION sessions_taxa_season(
    YR INTEGER, 
    SEAS INTEGER, 
    LOC TEXT, 
    EURINGS TEXT[]) 
RETURNS SETOF TEXT AS 
$BODY$ 
DECLARE 
    R RECORD; 
BEGIN 
    IF SEAS > 0 AND SEAS < 4 THEN 
    FOR R IN 
     SELECT DISTINCT session 
     FROM sync_utm32 
     WHERE 
     date_part('doy', gps_dt) 
     IN (SELECT DISTINCT TAXA_SEASON(SEAS, EURINGS)) AND 
     date_part('year', gps_dt) = YR AND 
     session ~~ LOC 
     ORDER BY SESSION 
    LOOP 
    RETURN NEXT R.SESSION; 
    END LOOP; 
    END IF; 

    IF SEAS=4 THEN 
    FOR R IN 
     SELECT DISTINCT SESSION 
     FROM sync_utm32 
     WHERE 
     date_part('doy', gps_dt) 
     IN (SELECT DISTINCT TAXA_SEASON(SEAS, EURINGS)) AND 
     date_part('year', gps_dt) = YR-1 AND 
     date_part('doy', gps_dt) >= 365/2 AND 
     session ~~ LOC 
     ORDER BY SESSION 
    LOOP 
    RETURN NEXT R.SESSION; 
    END LOOP; 

    FOR R IN 
     SELECT DISTINCT SESSION 
     FROM sync_utm32 
     WHERE 
     date_part('doy', gps_dt) 
     IN (SELECT DISTINCT TAXA_SEASON(SEAS, EURINGS)) AND 
     date_part('year', gps_dt) = YR AND 
     date_part('doy', gps_dt) < 365/2 AND 
     session ~~ LOC 
    LOOP 
     RETURN NEXT R.SESSION; 
    END LOOP; 

    END IF; 
    RETURN; 
END 
$BODY$ 
LANGUAGE plpgsql; 

結果:

SELECT SESSIONS_TAXA_SEASON(2016, 4,'%XX',ARRAY['00020','00030','00059']); 

sessions_taxa_season 
---------------------- 
2015-11-01-XX 
2015-12-07-XX 
2016-02-16-XX 
2016-01-21-XX 

其餘的是從perl DBI驅動sprintf模板。

+0

'FOR R IN SELECT ... RETURN NEXT;'可以通過'RETURN QUERY SELECT ...' – Abelisto

相關問題