【问题标题】:Can these queries be combined into one using a subquery?可以使用子查询将这些查询组合成一个吗?
【发布时间】:2021-09-15 13:55:22
【问题描述】:

一个查询按国家/地区查找汇总小计:

SELECT
    customer.country,
    SUM(i.subtotal) AS total
FROM
    invoices i
    LEFT JOIN customer ON i.customer_id = customer.id
WHERE
    status = 'Paid'
    AND datepaid BETWEEN '2020-05-01 00:00:00' AND '2020-06-01 00:00:00'
    AND customer.billing_day <> 0
    AND customer.register_date < '2020-06-01 00:00:00'
    AND customer.account_exempt = 'f'
    customer.country <> ''
GROUP BY
    customer.country;

另一个查询按州汇总美国客户的小计:

SELECT
    customer.state,
    SUM(i.subtotal) AS total
FROM
    invoices i
    LEFT JOIN customer ON i.customer_id = customer.id
WHERE
    status = 'Paid'
    AND datepaid BETWEEN '2020-05-01 00:00:00' AND '2020-06-01 00:00:00'
    AND customer.billing_day <> 0
    AND customer.register_date < '2020-06-01 00:00:00'
    AND customer.account_exempt = 'f'
    AND customer.country = 'US'
    AND customer.state <> ''
GROUP BY
    customer.state;

是否可以编写一个查询来返回每个国家的总数,如果国家是美国,也返回该州的总数?我读过子查询可用于组合两个聚合函数,但我不确定如何在这里完成。

【问题讨论】:

  • 与您的问题无关,但是:Postgres 9.2 是no longer supported,您应该尽快计划升级。
  • 合并它们的目的是什么?它们处于不同的级别(一个具有国家级数据,另一个具有州级数据)。你可以合并,但会造成更多的混乱。
  • 注意:WHERE 子句中的AND customer.billing_day ... 会将您的左连接降级为普通连接。
  • @wildplasser WHERE 子句中与客户表相关的所有条件都会降低 LEFT 连接的性能吗?感谢您指出这一点,我是新手。
  • 是的。通过推断customer.some_field = 'some_value',您隐含地强制 some_field 为 NOT NULL。

标签: sql postgresql postgresql-9.2


【解决方案1】:

您可以在group by 中使用两个键:

SELECT c.country,
       (CASE WHEN c.country = 'US' THEN c.state END) as state,
       SUM(i.subtotal) AS total
FROM invoices i JOIN
     customer c
     ON i.customer_id = c.id
WHERE i.status = 'Paid' AND
      i.datepaid >= '2020-05-01' AND
      i.datepaid < '2020-06-01' AND
      c.billing_day <> 0 AND
      c.register_date < '2020-06-01' AND
      c.account_exempt = 'f'
      c.country <> ''
GROUP BY c.country, (CASE WHEN c.country = 'US' THEN c.state END);

注意查询的其他更改:

  • 您的WHERE 子句将外连接变为内连接,因此LEFT JOIN 具有误导性。
  • 所有列引用都是合格的。
  • 大概,你想要五月的日期,所以我调整了逻辑。
  • 仅使用日期时无需包含时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多