I am trying to make a query to see the total price a customer has to pay when their order is completed, but I am having issues with this error statement. How do I get the correct query?
ERROR: argument of HAVING must be type boolean, not type money
Tables involved and inserting some fake quick data:
Some of the customers:
CREATE TABLE customers ( id integer PRIMARY KEY, first_name varchar(50), surname varchar(50), country varchar(200), email varchar(100) NOT NULL ); INSERT INTO customers VALUES (1, 'Mohamed', 'M', 'UK', 'momu@gmail.com'); INSERT INTO customers VALUES (2, 'Hass', 'H', 'UK', 'hass@gmail.com'); INSERT INTO customers VALUES (9, 'Zaza', 'Z', 'UK', 'zaza@gmail.com');
Some of the products:
CREATE TABLE store_products ( id integer PRIMARY KEY, name varchar(100), type varchar(50), description text, price money, quantity integer ); INSERT INTO store_products VALUES (1, 'Portable Chain Saw', 'Garden Tools', 'cant be asked for now LOREMIPSON', 21.00, 500); INSERT INTO store_products VALUES (3, 'Waterproof USB Plasma Lighter', 'Ignitions', 'For all you cool smokers look even cooler with the Plasma ARC lighter', 41.70, 3000); INSERT INTO store_products VALUES (4, 'Digital Multimeter', 'Measurement Tools', 'Work Safely with this Multimeter', 39.24, 333); INSERT INTO store_products VALUES (5, 'Cordless Screwdriver', 'Hand Tools', 'Get the job done just quicker', 97.20, 248); INSERT INTO store_products VALUES (6, 'Rustic Wooden Wall', 'Storage', 'Hang, Hang and Hang AWAY!!', 19.35, 995);
Then I combined these tables into a many-to-many relation table ordered_items:
CREATE TABLE ordered_items ( customers_id integer REFERENCES customers (id), store_products_id integer REFERENCES store_products (id), PRIMARY KEY (customers_id, store_products_id), quantity integer, order_date date ); INSERT INTO ordered_items VALUES (1, 4, 2, '2020, 09, 05'); UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE ordered_items.store_products_id = 4) WHERE id = 4; INSERT INTO ordered_items VALUES (1, 5, 1, '2020, 09, 05'); UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 5 AND customers_id = 1) WHERE id = 5; INSERT INTO ordered_items VALUES (2, 1, 1, '2020, 09, 25'); UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 1 AND customers_id = 2) WHERE id = 1; INSERT INTO ordered_items VALUES (2, 3, 10, '2020, 09, 25'); UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 3 AND customers_id = 2) WHERE id = 3; INSERT INTO ordered_items VALUES (9, 6, 20, '2021, 01, 04'); UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 6 AND customers_id = 9) WHERE id = 6;
As the customer buys an item in the store at the same time, I subtracted the original quantity they had in the store. Say, if they had 100 apples and the customer bought 5, the store has 95 apples left. This bit is all so far so good. Example:
UPDATE store_products SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 6 AND customers_id = 9) WHERE id = 6;
However, now when I try query the final price the customer has to pay, I am getting to this error
ERROR: argument of HAVING must be type boolean, not type money
And here is my query code so far:
-- If I put it as WHERE clause I get the same --- ERROR: argument of WHERE must be type boolean, not type money -- this is the WHERE query SELECT customers.first_name || ' ' || customers.surname AS customer_name, SUM(ordered_items.quantity) AS number_of_items_bought, SUM(store.price) AS final_price FROM customers JOIN ordered_items ON ordered_items.customers_id = customers.id JOIN store_products AS store ON store.id = ordered_items.store_products_id WHERE store.price * ordered_items.quantity GROUP BY 1; -- AND here is my HAVING Clause same problem -- ERROR: argument of HAVING must be type boolean, not type money SELECT customers.first_name || ' ' || customers.surname AS customer_name, SUM(ordered_items.quantity) AS number_of_items_bought, SUM(store.price) AS final_price FROM customers JOIN ordered_items ON ordered_items.customers_id = customers.id JOIN store_products AS store ON store.id = ordered_items.store_products_id GROUP BY 1 HAVING SUM(store.price) * ordered_items.quantity;
How can I fix that?
I want the results to give this:
customer_name | number_of_items_bought | final_price ---------------+------------------------+------------- Mohamed M | 3 | ú175.68 Hass H | 11 | ú438.00 Zaza Z | 20 | ú387.00 (3 rows)
And not this, which I am getting if I don’t include any HAVING or WHERE CLAUSE where I am trying to limit and have the price * quantity
-- With this query with which doesn't tell final price as PRICE * QUANTITY SELECT customers.first_name || ' ' || customers.surname AS customer_name, SUM(ordered_items.quantity) AS number_of_items_bought, SUM(store.price) AS final_price FROM customers JOIN ordered_items ON ordered_items.customers_id = customers.id JOIN store_products AS store ON store.id = ordered_items.store_products_id GROUP BY 1;
-- Wrong result customer_name | number_of_items_bought | final_price ---------------+------------------------+------------- Mohamed M | 3 | ú136.44 Hass H | 11 | ú62.70 Zaza Z | 20 | ú19.35 (3 rows)
How should I go about and get this query; I want price * quantity to show the right:
customer_name | number_of_items_bought | final_price ---------------+------------------------+------------- Mohamed M | 3 | ú175.68 Hass H | 11 | ú438.00 Zaza Z | 20 | ú387.00 (3 rows)
Advertisement
Answer
Cast 0
to money
to give zero the same type as the calculation and thus provide for a legal comparison:
having sum(store.price) * sum(ordered_items.quantity) > 0::money
See live demo.
Note also that you must use the aggregated (ie sum) value of ordered_items.quantity