可以使用子查询将这些查询组合成一个吗?

Posted

技术标签:

【中文标题】可以使用子查询将这些查询组合成一个吗?【英文标题】: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。 【参考方案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 具有误导性。 所有列引用都是合格的。 大概,你想要五月的日期,所以我调整了逻辑。 仅使用日期时无需包含时间。

【讨论】:

以上是关于可以使用子查询将这些查询组合成一个吗?的主要内容,如果未能解决你的问题,请参考以下文章

Scala Slick 将 Rep 子查询组合成一个 re

将子查询中的多个结果组合成一个逗号分隔值

用于将子行组合成单行视图的 SQL 查询

MYSQL 学习笔记记录整理之三:子查询

将这些查询组合成一个多表连接

将 3 个列表组合成 1 个 LINQ 查询 C#