I'm noob when it's come to DBMS so i wrote a query on couple of relations and i want to know what's the best way to do it because i don't feel good about my query.
Here are the relations:
CREATE TABLE "Product" (
"id" SERIAL PRIMARY KEY NOT NULL,
"name" text,
"unit_price" float8,
"quantity" integer,
"produce_per_day_ratio" integer,
"sold_till_now" integer
);
CREATE TABLE "Order" (
"id" SERIAL PRIMARY KEY NOT NULL,
"personal_id" bigint,
"product_id" bigint,
"quantity" bigint,
"company" text
);
CREATE TABLE "SalesManager" (
"id" SERIAL PRIMARY KEY NOT NULL,
"fName" text,
"lName" text,
"age" integer,
"gender" bigint,
"salary" bigint,
"profit" float8
);
CREATE TABLE "Gender" (
"id" SERIAL PRIMARY KEY NOT NULL,
"name" text
);
ALTER TABLE "Order" ADD FOREIGN KEY ("personal_id") REFERENCES "SalesManager" ("id");
ALTER TABLE "Order" ADD FOREIGN KEY ("product_id") REFERENCES "Product" ("id");
ALTER TABLE "SalesManager" ADD FOREIGN KEY ("gender") REFERENCES "Gender" ("id");
So the question is "show the name of people who have sold the most products?" and by most sold i meant (quantity * unit_price)
EDIT:this is the updated query:
WITH orderProduct AS(
SELECT
O.personal_id as pId ,
sum(O.quantity * P.unit_price) as sold_amount,
RANK() OVER (ORDER BY sum(O.quantity * P.unit_price) DESC) as rank
FROM "Order" AS O
INNER JOIN "Product" AS P ON O.product_id = P.id
GROUP BY O.personal_id
)
SELECT concat("fName" , ' ' , "lName") as name , orderProduct.sold_amount
FROM "SalesManager"
INNER JOIN orderProduct ON id = pId
WHERE rank = 1;
So how bad is it ? :(
PS: i'm using postgres 12.2
OP
) - you can apply therank()
directly inside the CTE. But apart from that (and the dreaded quoted identifiers) this doesn't look too bad to me.SELECT O."personal_id" as "pId" , sum(O."quantity" * P."unit_price") as "sold_amount", RANK() OVER (ORDER BY "sold_amount" DESC) as "rank" FROM "Order" AS O INNER JOIN "Product" AS P ON O."product_id" = P.id GROUP BY O."personal_id"
but this throws an error saying sold_amount does not exists. Thank you.RANK() OVER (ORDER BY sum(O."quantity" * P."unit_price") DESC) as "rank"
isn't this calculating the sum twice and isn't that bad ?rank
isn't that an extra calculation? and is it ok to do that ?