'Create a procedure to get grouped by data from a table to another given a certain year and quarter in PostgreSql
I am trying to get this code to work. I want to create a procedure that given a certain year and quarter it fills a table (tb_quarter) with grouped by information of another two tables.
So far I have this:
CREATE OR REPLACE PROCEDURE pr_calc_quarter
(year tb_quarter.year%type, quarter tb_quarter.quarter%type) AS $$
BEGIN
INSERT INTO tb_quarter
SELECT
EXTRACT(quarter FROM l.last_update_date) AS quarter,
EXTRACT(year FROM l.last_update_date) AS year,
cust_no,
ROUND(l.iva_amount/l.net_amount*100) AS iva_percent,
SUM(l.iva_amount) AS amount
FROM
tb_lines l
INNER JOIN
tb_invoice i USING (invoice_id)
GROUP BY
cust_no,
iva_percent,
year,
quarter;
END;
$$LANGUAGE plpgsql
;
So far, the procedure works to fill in the table, but without taking into account the year and quarter I put in.
I am unable to solve the code in order to select only the data that matches the year and the quarter.
I've tried this:
CREATE OR REPLACE PROCEDURE pr_calc_quarter
(year tb_quarter.year%type, quarter tb_quarter.quarter%type) AS $$
BEGIN
SELECT
EXTRACT(quarter FROM l.last_update_date) AS l_quarter,
EXTRACT(year FROM l.last_update_date) AS l_year,
cust_no,
ROUND(l.iva_amount/l.net_amount*100) AS iva_percent,
SUM(l.iva_amount) AS amount
FROM
tb_lines l
INNER JOIN
tb_invoice i USING (invoice_id)
WHERE l_quarter = quarter
AND l_year = year
GROUP BY
cust_no,
iva_percent,
l_year,
l_quarter;
INSERT INTO tb_quarter VALUES (quarter,year,iva_percent,amount);
END;
$$LANGUAGE plpgsql
;
But it returns an error saying the column l_quarter doesn't exist. I've also tried to change the names of the input parameters (year + quarter), but it also returns error saying it is not allowed.
These are the tables I am working with:
CREATE TABLE tb_quarter
(
quarter INTEGER NOT NULL,
year INTEGER NOT NULL,
cust_no CHARACTER (5) NOT NULL,
iva_percent INTEGER NOT NULL,
amount REAL NOT NULL,
CONSTRAINT pk_tb_quarter PRIMARY KEY(quarter, year, cust_no, iva_percent),
CONSTRAINT fk_tb_customer FOREIGN KEY (cust_no) REFERENCES tb_customer(cust_no)
);
CREATE TABLE erp.tb_lines (
invoice_id INT NOT NULL,
line_id INT NOT NULL,
line_num INT NOT NULL,
item CHARACTER(5),
description CHARACTER VARYING(120) NOT NULL,
net_amount REAL NOT NULL,
iva_amount REAL NOT NULL,
last_updated_by CHARACTER VARYING(20) DEFAULT 'SYSTEM',
last_update_date DATE NOT NULL,
CONSTRAINT pk_lines PRIMARY KEY (line_id),
CONSTRAINT fk_lines_invoice FOREIGN KEY (invoice_id) REFERENCES erp.tb_invoice (invoice_id)
);
CREATE TABLE erp.tb_invoice (
co_code CHARACTER(3) NOT NULL,
invoice_id INT NOT NULL,
invoice_no CHARACTER VARYING(15) NOT NULL,
cust_no CHARACTER(5) NOT NULL,
site_id INT NOT NULL,
payed CHARACTER(1) NOT NULL DEFAULT 'N',
net_amount REAL NOT NULL,
iva_amount REAL NOT NULL,
tot_amount REAL NOT NULL,
last_updated_by CHARACTER VARYING(20) DEFAULT 'SYSTEM',
last_update_date DATE NOT NULL,
CONSTRAINT pk_invoice PRIMARY KEY (invoice_id),
CONSTRAINT fk_invoice_company FOREIGN KEY (co_code) REFERENCES erp.tb_company (co_code),
CONSTRAINT fk_invoice_customer FOREIGN KEY (cust_no) REFERENCES erp.tb_customer (cust_no),
CONSTRAINT fk_invoice_site FOREIGN KEY (site_id) REFERENCES erp.tb_site (site_id)
);
Finally I was able to solve it using nbk's answer and changing it a little bit:
CREATE OR REPLACE PROCEDURE pr_calc_quarter
(year tb_quarter.year%type, quarter tb_quarter.quarter%type) AS $$
BEGIN
INSERT INTO tb_quarter
SELECT
EXTRACT(quarter FROM l.last_update_date) AS l_quarter,
EXTRACT(year FROM l.last_update_date) AS l_year,
cust_no,
ROUND(l.iva_amount/l.net_amount*100) AS iva_percent,
SUM(l.iva_amount) AS amount
FROM
tb_lines l
INNER JOIN
tb_invoice i USING (invoice_id)
WHERE
EXTRACT(quarter FROM l.last_update_date) = quarter
AND EXTRACT(year FROM l.last_update_date) = year
GROUP BY
cust_no,
iva_percent,
l_year,
l_quarter;
END;
$$LANGUAGE plpgsql
;
Solution 1:[1]
Postgres doesn't support using aliases anywhere, so you could simply repeat the extract
CREATE OR REPLACE PROCEDURE pr_calc_quarter
(_year tb_quarter.year%type, _quarter tb_quarter.quarter%type) AS $$
BEGIN
INSERT INTO tb_quarter
SELECT
EXTRACT(quarter FROM l.last_update_date) AS l_quarter,
EXTRACT(year FROM l.last_update_date) AS l_year,
cust_no,
ROUND(l.iva_amount/l.net_amount*100) AS iva_percent,
SUM(l.iva_amount) AS amount
FROM
tb_lines l
INNER JOIN
tb_invoice i USING (invoice_id)
WHERE
EXTRACT(quarter FROM l.last_update_date) = _quarter
AND EXTRACT(year FROM l.last_update_date) = _year;
GROUP BY
cust_no,
iva_percent,
year,
quarter
END;
$$LANGUAGE plpgsql;
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | nbk |
