I`m trying to create some basic DB for my backend API.
I want a one-to many relation with order and order_products so there can be only one order(id) but there can be more rows in "order_products" with the same "order_id" but i get a syntax error:
syntax error at or near "order"
LINE 2: "order_id" int REFERENCES order(id),
^
and i dont know why (This is in the order_products table).
CREATE TABLE IF NOT EXISTS "customers" (
"id" SERIAL PRIMARY KEY,
"first_name" varchar,
"last_name" varchar,
"username" varchar,
"password" varchar,
"email" varchar UNIQUE,
"is_admin" boolean
);
CREATE TABLE IF NOT EXISTS "address" (
"customer_id" int REFERENCES customers(id),
"zipcode" int,
"country" varchar,
"city" varchar,
"street_name" varchar,
"stree_number" varchar,
"mobile_number" int
);
CREATE TABLE IF NOT EXISTS "products" (
"id" SERIAL PRIMARY KEY,
"item_name" varchar UNIQUE,
"description" text,
"image_url" varchar,
"price" float
);
CREATE TABLE IF NOT EXISTS "order" (
"customer_id" int REFERENCES customers(id),
"id" SERIAL PRIMARY KEY,
"date_of_purchase" date,
"total_price" int
);
CREATE TABLE IF NOT EXISTS "order_products" (
"order_id" int REFERENCES order(id),
"product_id" int REFERENCES products(id),
"quantity" int,
"total_price" int,
UNIQUE(order_id, product_id)
);
CREATE TABLE IF NOT EXISTS "cart" (
"customer_id" int REFERENCES customers(id),
"id" SERIAL PRIMARY KEY,
"date_of_purchase" date,
"total_price" int
);
CREATE TABLE IF NOT EXISTS "cart_products" (
"cart_id" int REFERENCES cart(id),
"product_id" int REFERENCES products(id),
"quantity" int,
"total_price" int,
UNIQUE(cart_id, product_id)
);
order is a reserved keyword, so you need to enclose it always in double quotes:
"order_id" int REFERENCES "order"(id),
In general I recommend to never use double quotes. For that you would need to find a different name for the order table that doesn't require quoting
I am facing a problem, I have developed a function with dynamic whare clause.
When every I run the query separatly it returns the value much faster while running with EXECUTE it give allot of time. "cv."SessionId" = ''f0d1c0e1-b13c-4aff-b1f7-432183b06d10'' AND cv."CampusId" = ''4f4310a3-9c36-49c2-8456-5604cb7e9a62'' AND cv."ProgramId"=''e50efffa-40a3-4eb9-a65b-65106967add7'' AND cv."ShiftId"=''414de073-ca8b-4a84-80bc-52c2030b4eeb'' AND cv."ProgramDetailId"=''8d1ce321-d015-4336-ba92-dcd2c8b6443b'' AND cv."ClassId"=''8931d744-acc9-4776-a03a-2b705038ea48'' AND cv."SectionId"=''83c507d0-8f61-4a28-b221-88625482953f'' AND cv."CollectorId"=''e58d2fbf-839a-49a1-b1ce-92e7c26a305b'' AND cv."FeeHeadId"=''5721bc8f-4e9c-49d0-a992-6b846fafb9db'' AND cv."PaidDate" >= ''2020-07-01'' AND cv."PaidDate" <= ''2020-08-07'' ORDER BY cv."ChallanNo" ASC" this is where clause parameter which change every time. some time two some time four or five. the following is my function which i want to optimize.
declare feeheadrow record;
declare paiddate date;
declare rollno text;
declare admisformid uuid;
declare feeheadname text;
declare instNo int4;
declare stdname text;
declare fathername text;
declare refno text;
declare classid uuid;
declare campusprogid uuid;
declare stdid uuid;
declare challano text;
declare campusid uuid;
declare sessionid uuid;
declare progdetailid uuid;
declare campusname text;
declare descrip text;
declare shiftname text;
declare genderid uuid;
declare shiftid uuid;
declare remarks text;
declare sessionname text;
declare totalamount int4;
declare programid uuid;
declare collectorid uuid;
BEGIN
DROP TABLE IF EXISTS "FeeReport";
DROP TABLE IF EXISTS "FeeHeads";
create temp table "FeeReport"("NewID" uuid, "PaidDate" Date, "RollNo" text, "AdmissionFormId" uuid, "FeeHeadName" text, "InstallmentNo" int4, "StudentName" text, "FatherName" text, "RefferenceNo" text, "ClassId" uuid, "CampusProgramId" uuid, "FeeHeadId" uuid,
"FeeAmount" int4, "PayableAmount" int4, "StudentId" uuid, "ChallanNo" text, "CampusId" uuid, "SessionId" uuid,
"ProgramDetailId" uuid, "CampusName" text, "Description" text, "ShiftName" text, "GenderId" uuid,
"ShiftId" uuid,"Remarks" text, "ScholarshipCriteriaId" uuid, "ScholarshipCriteriaName" text, "SessionName" text, "TotalAmount" int4
, "ProgramId" uuid, "CollectorId" uuid
) on commit DROP;
create temp table "FeeHeads"("FeeHeadId" UUID, "FullName" TEXT) on commit drop;
insert into "FeeReport"
SELECT * FROM "Query"('cv.*', '"Fee"."VWFeeStatement2" AS cv', whereclause) AS
"FeeRecords" ("NewID" uuid, "PaidDate" date, "RollNo" text, "AdmissionFormId" uuid, "FeeHeadName" text, "InstallmentNo" int4, "StudentName" text, "FatherName" text, "RefferenceNo" text, "ClassId" uuid, "CampusProgramId" uuid, "FeeHeadId" uuid, "FeeAmount" int4, "PayableAmount" int4, "StudentId" uuid, "ChallanNo" text, "CampusId" uuid, "SessionId" uuid, "ProgramDetailId" uuid, "CampusName" text, "Description" text, "ShiftName" text, "GenderId" uuid, "ShiftId" uuid, "Remarks" text, "ScholarshipCriteriaId" uuid, "ScholarshipCriteriaName" text, "SessionName" text, "TotalAmount" int4,"ProgramId" uuid,"CollectorId" uuid);
insert into "FeeReport"
SELECT * FROM "Query"('cv.*', '"Fee"."VWFeeStatementOther2" AS cv', whereclause) AS
"FeeRecords" ("NewID" uuid, "PaidDate" date, "RollNo" text, "AdmissionFormId" uuid, "FeeHeadName" text, "InstallmentNo" int4, "StudentName" text, "FatherName" text, "RefferenceNo" text, "ClassId" uuid, "CampusProgramId" uuid, "FeeHeadId" uuid, "FeeAmount" int4, "PayableAmount" int4, "StudentId" uuid, "ChallanNo" text, "CampusId" uuid, "SessionId" uuid, "ProgramDetailId" uuid, "CampusName" text, "Description" text, "ShiftName" text, "GenderId" uuid, "ShiftId" uuid, "Remarks" text, "ScholarshipCriteriaId" uuid, "ScholarshipCriteriaName" text, "SessionName" text, "TotalAmount" int4,"ProgramId" uuid,"CollectorId" uuid);
insert into "FeeHeads"
SELECT DISTINCT fh."FeeHeadId", fh."FullName" FROM "Fee"."FeeHead" AS fh, "FeeReport" fr
WHERE fr."FeeHeadId" = fh."FeeHeadId";
FOR vwfeestatementrow in select distinct f."AdmissionFormId"
from "FeeReport" f
LOOP
select vw."PaidDate", vw."RollNo", vw."AdmissionFormId", vw."InstallmentNo", vw."StudentName", vw."FatherName" , vw."RefferenceNo", vw."ClassId",
vw."CampusProgramId", vw."StudentId", vw."ChallanNo", vw."CampusId" , vw."SessionId",
vw."ProgramDetailId", vw."CampusName", vw."Description", vw."ShiftName", vw."GenderId",vw."ShiftId", vw."SessionName", vw."TotalAmount",vw."ProgramId",vw."CollectorId"
INTO paiddate,rollno,
admisformid,instNo,stdname,fathername,refno,classid,
campusprogid,stdid,challano,campusid,sessionid,progdetailid,campusname,descrip,shiftname,genderid,shiftid,sessionname,totalamount,programid,collectorid
from "FeeReport" vw where vw."AdmissionFormId"=vwfeestatementrow."AdmissionFormId" limit 1;
FOR feeheadrow IN SELECT fh."FeeHeadId",fh."FullName" FROM "FeeHeads" fh WHERE (fh."FeeHeadId" NOT IN (
SELECT ins."FeeHeadId" FROM "FeeReport" AS ins WHERE ins."AdmissionFormId" = vwfeestatementrow."AdmissionFormId"))
LOOP
INSERT INTO "FeeReport"("NewID","PaidDate","RollNo","AdmissionFormId","FeeHeadName","InstallmentNo","StudentName",
"FatherName","RefferenceNo","ClassId", "CampusProgramId","FeeHeadId",
"FeeAmount", "PayableAmount", "StudentId", "ChallanNo", "CampusId", "SessionId",
"ProgramDetailId", "CampusName", "Description", "ShiftName", "GenderId",
"ShiftId","Remarks", "ScholarshipCriteriaId", "ScholarshipCriteriaName", "SessionName", "TotalAmount","ProgramId",
"CollectorId"
)
VALUES(uuid_generate_v1(),paiddate,rollno,vwfeestatementrow."AdmissionFormId",
feeheadrow."FullName",instNo,stdname,fathername
,refno,classid,campusprogid,feeheadrow.
"FeeHeadId",0,0,stdid,challano,campusid,
sessionid,progdetailid,campusname,descrip,shiftname,genderid,shiftid,'',null,'',
sessionname,totalamount,programid,collectorid
);
END LOOP;
END LOOP;
-- DELETE FROM "Student" AS st WHERE st."AdmissionFormId" IN (SELECT af."AdmissionFormId" FROM "Fee"."StudentFeeStructure" AS sf, "Admission"."AdmissionForm" AS af WHERE sf."AdmissionFormId" = af."AdmissionFormId" AND af."CampusProgramId" = campusprogramid AND sf."ConcessionDetailId" IS NOT NULL);
RETURN query Select fr.* from "FeeReport" as fr ORDER BY fr."ChallanNo", fr."FeeHeadName";
END```
I am using postgresql 9.6 and want to merge data from multiple rows into one. I'm using 4 tables(the table format and data cannot be changed)
Tables are-
"id" int4 DEFAULT nextval('product_a_seq'::regclass) NOT NULL,
"name" varchar(255) COLLATE "default",
"organization_id" int4,
"description" text COLLATE "default",
"image" varchar(255) COLLATE "default" DEFAULT 'https://abcd.com'::character varying,
"deleted" bool,
"price" float4,
"currency_id" int4,
CONSTRAINT "product_pkey" PRIMARY KEY ("id")
)
CREATE TABLE "public"."product_asset" (
"id" int4 DEFAULT nextval('product_asset_a_seq'::regclass) NOT NULL,
"product_id" int4,
"asset_type" varchar(255) COLLATE "default",
"asset_url" text COLLATE "default",
"asset_value" text COLLATE "default",
"asset_name" text COLLATE "default",
CONSTRAINT "product_asset_pkey" PRIMARY KEY ("id")
)
CREATE TABLE "public"."user" (
"id" int4 DEFAULT nextval('istar_user_a_seq'::regclass) NOT NULL,
"mobile" varchar COLLATE "default",
"name" varchar(255) COLLATE "default",
"organization_id" int4,
CONSTRAINT "istar_user_pkey" PRIMARY KEY ("id")
)
CREATE TABLE "public"."pipeline_product" (
"pipeline_id" int4 NOT NULL,
"product_id" int4 NOT NULL,
CONSTRAINT "uq_pipeline_product_pipeline_id_product_id" UNIQUE ("pipeline_id", "product_id")
)
For each product there can be multiple assets and pipelines
I want all data grouped according to product.id, here's my initial attempt
SELECT
product. ID AS pid,
product. NAME AS pname,
product.price,
product.currency_id,
product.description,
product_asset.asset_type,
product_asset.asset_url,
product_asset.asset_name,
product_asset.asset_value,
product_asset. ID AS asset_id,
String_agg ( pipeline_product.pipeline_id :: TEXT, ',' ) AS process_id
FROM
product
LEFT JOIN product_asset ON product_asset.product_id = product. ID
AND product_asset.is_active = TRUE
LEFT JOIN pipeline_product ON pipeline_product.product_id = product. ID
WHERE
organization_id IN (
SELECT
"user" .organization_id
FROM
"user"
WHERE
"user" . ID = 218915
)
AND deleted = FALSE
GROUP BY
pid,
product_asset. ID,
product_asset.asset_type,
product_asset.asset_name,
product_asset.asset_url,
product_asset.asset_value
and i get output as:
I need only one entry for the product.id and everything else should be in a single column,
I am using string_agg() function. What am I missing?
I see three issues in your query:
product_asset.asset_url is not unique, use max(product_asset.asset_url)
product_asset.ID is not unique, so you cannot group it. Use min(product_asset.ID) or max(product_asset. ID)
String_agg(pipeline_product.pipeline_id :: TEXT, ',') does not return always the same value, because they are not sorted, You should add ORDER BY pipeline_product.product_id, pipeline_product.pipeline_id.
I have this stored procedure in PostgreSQL where I want to make an insert in a table. I get some parameters from the procedure and using them I have tried to select other attributes on other tables.
This is my stored procedure:
CREATE OR REPLACE FUNCTION "public"."prc_sales_invoice_header_insert"("customercode" varchar, "sales_note" varchar, "automatic_payment_id" int4, "cash_register_code" varchar,...etc)
RETURNS "pg_catalog"."void" AS $BODY$
--declaring variables to store data from the tables
DECLARE
salesdate date;
salesdocumentserial varchar;
currencycode varchar;
currencycode2 varchar;
customername varchar;
warehousecode varchar;
......etc.
BEGIN
--getting values from tables and storing to variables
SELECT "name" into customername from public."customers" where "customer_code" = customercode;
SELECT CURRENT_DATE into salesdate;
SELECT max(sales_invoice_header_id) into salesdocumentserial from public."sales_invoice_header";
.....
--inserting values
INSERT INTO public."sales_invoice_header"("sales_date",
"sales_document_serial",
"currency_code",
"currency_code2",
"customer_code",
....
VALUES(
salesdate,
salesdocumentserial,
currencycode,
currencycode2,
customer_code,
.....)
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
When I try to execute it throws an error saying:
"ERROR: column "customer_code" does not exist", "HINT: There is a column named "customer_code" in table "sales_invoice_header", but it cannot be referenced from this part of the query."
Table customers exists and there is a column named costomer_code but I don't understand why it cannot reference it.
Table customers:
-- ----------------------------
-- Table structure for customers
-- ----------------------------
DROP TABLE IF EXISTS "public"."customers";
CREATE TABLE "public"."customers" (
"customer_id" int4 NOT NULL DEFAULT nextval('"Customers_CustomerId_seq"'::regclass),
"customer_code" varchar COLLATE "pg_catalog"."default",
"barcode" varchar COLLATE "pg_catalog"."default",
"qr_code" varchar COLLATE "pg_catalog"."default",
"tax_id" varchar COLLATE "pg_catalog"."default",
"business_id" varchar COLLATE "pg_catalog"."default",
"city_id" int8,
"mobile" varchar COLLATE "pg_catalog"."default",
"accounting_number" varchar COLLATE "pg_catalog"."default",
"name" varchar COLLATE "pg_catalog"."default"
);
Can anyone help me with this, what I am doing wrong? Or is this the correct way of doing things?
Thanks in advance.
INSERT INTO public."sales_invoice_header"("sales_date",
"sales_document_serial",
"currency_code",
"currency_code2",
"customer_code",
....
VALUES(
salesdate,
salesdocumentserial,
currencycode,
currencycode2,
customer_code,
here customer_code is not a variable, nor literal - it is a column name. yet you don't select it form table - you try to use it in VALUES - won't work. either use
insert into ... select ...,customer_code from sales_invoice_header
or
insert into ... values(..., VAR_customer_code)
or
insert into ... values(..., 'value_customer_code')
edit:
as a_horse_with_no_name noticed my VAR_customer_code, must be your customercode first argument?..