【问题标题】:What causes error "argument of HAVING must be type boolean, not type money", and how do I fix it?是什么导致错误“HAVING 的参数必须是布尔类型,而不是金钱类型”,我该如何解决?
【发布时间】:2021-10-07 04:34:02
【问题描述】:

我正在尝试查询以查看客户在完成订单后必须支付的总价格,但我遇到了此错误语句的问题。如何获得正确的查询?

错误:HAVING 的参数必须是 boolean 类型,而不是 money 类型

涉及的表格并插入了一些虚假的快速数据:

部分客户:

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');

部分产品:

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);

然后我将这些表组合成一个多对多关系表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;

当客户同时在商店购买商品时,我减去了他们在商店中的原始数量。比如说,如果他们有 100 个苹果,而顾客买了 5 个,那么商店还剩下 95 个苹果。到目前为止,这一切都很好。示例:

UPDATE store_products
SET quantity = quantity - (SELECT quantity FROM ordered_items WHERE store_products_id = 6 AND customers_id = 9)
WHERE id = 6;

但是,现在当我尝试查询客户必须支付的最终价格时,我遇到了这个错误

错误:HAVING 的参数必须是 boolean 类型,而不是 money 类型

到目前为止,这是我的查询代码:

-- 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;

我该如何解决这个问题?

我希望结果是这样的:

 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)

而不是这个,如果我不包含任何我试图限制并具有价格 * 数量的 HAVING 或 WHERE 条款,我会得到这个

-- 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)

我应该怎么做才能得到这个查询;我希望价格 * 数量显示正确:

 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)

【问题讨论】:

  • 我认为这个错误很明显。 SUM(store.price) * ordered_items.quantity 不是布尔表达式,而是一个数字。你的意思是写having SUM(store.price) * ordered_items.quantity > 0
  • 不相关,但是:don't use money
  • @a_horse_with_no_name 当我把这个有子句放在末尾时,我收到了这个错误错误:运算符不存在:货币>整数第 10 行:有总和(商店.价格)*ordered_items.quantity > 0 ; ^ 提示:没有运算符匹配给定的名称和参数类型。您可能需要添加显式类型转换。上箭头指向 '>'

标签: sql postgresql group-by


【解决方案1】:

0 转换为money 以将零与计算的类型相同,从而提供合法的比较:

having sum(store.price) *
  sum(ordered_items.quantity) > 0::money

live demo

另请注意,您必须使用ordered_items.quantity 的聚合(即总和)值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 2021-03-29
    • 1970-01-01
    • 2023-01-13
    • 1970-01-01
    相关资源
    最近更新 更多