Postgresql

聚合函式的問題

  • February 4, 2019

我想在我的leggeapprovata表中插入一個元組,但該表從其他 4 個表中獲取屬性。這 4 個表之一是votazione表,它從中獲取 6 個屬性。兩個沒有給我錯誤,但是對於其他 4 個屬性,它給了我同樣的錯誤,即您不能maxwhere子句中使用聚合函式。

為了避免選擇給我更多的行,因為在投票中有更多具有不同日期的元組,我想要具有最新日期的元組(MAX (votazione.data)),但這給了我之前所說的錯誤:

ERROR: the aggregation functions are not allowed in GROUP BY LINE 17: 
... ect votazione.favorevoli from votazione group by (MAX(vota ... ^
********** Error **********
ERROR: aggregate functions are not allowed in GROUP BY SQL state: 42803

我也嘗試過where, case when, having,但我仍然收到一條錯誤消息。

插入/選擇語句

以下是我要執行的語句。

INSERT INTO leggeapprovata (titolo, 
    relatore,
    numerolegislatura,
    testo,
    votisi,
    votino,
    astenuti,
    datapromulgazione,
    promulgatada,
    numlegge,
    dataapprovazionecamera,
    dataapprovazionesenato) 
 SELECT ddl.titolo, 
    ddl.relatore,
    legislatura.numero,
    ddl.testo,
    (select votazione.favorevoli from votazione group by (MAX(votazione.data)) AND tipoassemblea='senato'),
    (select votazione.contrari  from votazione group by (MAX(votazione.data)) AND tipoassemblea='senato'),
    (select votazione.astenuti  from votazione group by (MAX(votazione.data)) AND tipoassemblea='senato'),
    promulgazione.data,
    promulgazione.presidente,
    (select votazione.codice  from votazione  group by (MAX(votazione.data)) AND tipoassemblea='senato'),
    (select MAX(votazione.data) from votazione,ddl where tipoassemblea='camera' and votazione.ddl=ddl.titolo),
    (select MAX(votazione.data) from votazione,ddl where tipoassemblea='senato' and votazione.ddl=ddl.titolo)
  FROM ddl, legislatura, votazione, promulgazione
  WHERE ddl.promulgato='si' and ddl.titolo=promulgazione.ddl and (promulgazione.data between legislatura.datainizio and legislatura.datafine);

表定義

CREATE TABLE public.leggeapprovata
(
 titolo character varying(1000) NOT NULL,
 numerolegislatura integer NOT NULL,
 testo text,
 votisi integer,
 votino integer,
 astenuti integer,
 datapromulgazione date,
 promulgatada character varying(100),
 relatore character varying(100)[] NOT NULL,
 dataapprovazionecamera date,
 dataapprovazionesenato date,
 numlegge character(10),
 CONSTRAINT leggeapprovatapkey PRIMARY KEY (titolo, numerolegislatura, relatore),
 CONSTRAINT leggeapprovatanumerolegislaturafkey FOREIGN KEY (numerolegislatura)
     REFERENCES public.legislatura (numero) MATCH SIMPLE
     ON UPDATE NO ACTION ON DELETE NO ACTION,
 CONSTRAINT leggeapprovatapromulgatadafkey FOREIGN KEY (promulgatada)
     REFERENCES public.presidentedellarepubblica (presidente) MATCH SIMPLE
     ON UPDATE NO ACTION ON DELETE NO ACTION,
 CONSTRAINT leggeapprovatatestofkey FOREIGN KEY (testo, relatore)
     REFERENCES public.ddl (testo, relatore) MATCH SIMPLE
     ON UPDATE NO ACTION ON DELETE NO ACTION,
 CONSTRAINT leggeapprovatatitolofkey FOREIGN KEY (titolo, datapromulgazione)
     REFERENCES public.promulgazione (ddl, data) MATCH SIMPLE
     ON UPDATE NO ACTION ON DELETE NO ACTION,
 CONSTRAINT leggeapprovatavotisifkey FOREIGN KEY (votisi, votino, astenuti, numlegge)
     REFERENCES public.votazione (favorevoli, contrari, astenuti, codice) MATCH SIMPLE
     ON UPDATE NO ACTION ON DELETE NO ACTION,
 CONSTRAINT leggeapprovatatitolonumerolegislaturatestorelatorenukey UNIQUE (titolo, numerolegislatura, testo, relatore, numlegge)
)
WITH (
 OIDS=FALSE
);
ALTER TABLE public.leggeapprovata
 OWNER TO postgres;
GRANT ALL ON TABLE public.leggeapprovata TO public;
GRANT ALL ON TABLE public.leggeapprovata TO postgres WITH GRANT OPTION;

觸發器定義

-- Trigger: inserimentoinleggeapprovata on public.leggeapprovata

-- DROP TRIGGER inserimentoinleggeapprovata ON public.leggeapprovata;

CREATE TRIGGER inserimentoinleggeapprovata
 BEFORE INSERT
 ON public.leggeapprovata
 FOR EACH ROW
 WHEN ((pg_trigger_depth() = 0))
 EXECUTE PROCEDURE public.inserimentoinleggeapprovata();
ALTER TABLE public.leggeapprovata DISABLE TRIGGER inserimentoinleggeapprovata;
COMMENT ON TRIGGER inserimentoinleggeapprovata ON public.leggeapprovata IS 'when (pg_trigger_depth()=)livello di annidamento corrente dei trigger PostgreSQL (0 se non viene chiamato, direttamente o indirettamente, da un trigger)';



CREATE TRIGGER inserimentoinleggeapprovata
 BEFORE INSERT
 ON public.leggeapprovata
 FOR EACH ROW
 WHEN ((pg_trigger_depth() = 0))
 EXECUTE PROCEDURE public.inserimentoinleggeapprovata();
COMMENT ON TRIGGER inserimentoinleggeapprovata ON public.leggeapprovata IS 'when (pg_trigger_depth()=)livello di annidamento corrente dei trigger PostgreSQL (0 se non viene chiamato, direttamente o indirettamente, da un trigger)';

函式定義

-- Function: public.inserimentoinleggeapprovata()

-- DROP FUNCTION public.inserimentoinleggeapprovata();

CREATE OR REPLACE FUNCTION public.inserimentoinleggeapprovata()
 RETURNS trigger AS
$BODY$
begin
if exists (select 1 from leggeapprovata
where leggeapprovata.titolo = NEW.titolo)
  THEN 
       RAISE EXCEPTION '% già ESISTENTE IN leggeapprovata', NEW.titolo;
  ELSE  RETURN new;
  end if;
end;

$BODY$
 LANGUAGE plpgsql VOLATILE
 COST 1000;
ALTER FUNCTION public.inserimentoinleggeapprovata()
 OWNER TO postgres;
GRANT EXECUTE ON FUNCTION public.inserimentoinleggeapprovata() TO postgres;
GRANT EXECUTE ON FUNCTION public.inserimentoinleggeapprovata() TO public;

我將不勝感激有關錯誤消息的任何回饋。


投票表數據

這是votazione表格的第一張圖片:

在此處輸入圖像描述

這是votazione表格的第二張圖片:

在此處輸入圖像描述

根據您要實現的目標,您的子選擇可能就像轉換它一樣簡單:

select votazione.favorevoli 
   from votazione 
group by (MAX(votazione.data)) 
AND tipoassemblea='senato'

…對此:

select votazione.favorevoli 
   from votazione 
where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato')
AND tipoassemblea='senato'

上面的語句已經修改

這可能會為您的查詢生成單個數據集,但這取決於您擁有的數據。

正如錯誤消息正確指出的那樣,您不能在GROUP BY子句中使用聚合函式。

有效的陳述是:

select votazione.favorevoli 
   from votazione 
where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato') 
AND tipoassemblea='senato'

上面的語句已經修改

…如前所述,或者可能:

select votazione.favorevoli, MAX(votazione.data) 
   from votazione 
where tipoassemblea='senato'
GROUP BY votazione.favorevoli

然而,這將產生兩個值。

請查看官方文件以了解如何使用聚合函式(PostgreSQL 文件)。

您可能正在尋找類似的東西:

SELECT ddl.titolo, 
...
(select votazione.favorevoli from votazione where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato') AND tipoassemblea='senato'),
(select votazione.contrari  from votazione where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato') AND tipoassemblea='senato'),
(select votazione.astenuti  from votazione where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato') AND tipoassemblea='senato'),
...
(select votazione.codice  from votazione  where votazione.data = (select MAX(votazione.data) from votazione where tipoassemblea='senato') AND tipoassemblea='senato'),
...

引用自:https://dba.stackexchange.com/questions/228545