0

我希望我在下面正确地把查询放在一起。我已经从更大的东西简化了。但是从这个例子中我的问题应该很清楚了。

在最里面的查询中nest1,假设结果返回发票 123 的三个条目。发票已创建 (1),然后进行了两次现金存款 (2, 3),其中第二次存款 (3) 还清了发票。从该结果集中,我正在汇总总和。我也得到了paid_off_date,只有其中一行会有。

我很高兴接受有关设计此查询的更好方法的教育,但我不明白为什么我必须一直选择聚合。为什么,例如,当我选择SUM(cash_deposit) AS 'cash_deposit'in时nest2,我还必须SUM(cash_deposit)在最外层的查询中选择?一旦在子查询中聚合,为什么不传递聚合?为什么我必须在每个级别继续按 id 分组?

SELECT id, SUM(cash_deposit), MAX(paid_off_date), MAX(job_phase), MAX(cust_id)
FROM
(
    SELECT id AS id, SUM(cash_deposit) AS 'cash_deposit', MAX(paid_off_date) AS 'paid_off_date', MAX(job_phase) AS 'job_phase'
    FROM
    (
         SELECT id, cash_deposit, paid_off_date
         FROM invoice
         GROUP BY id
    ) nest1
    JOIN    job j
            ON nest1.id = j.id
    GROUP BY id
) nest2
JOIN    customer c
        ON c.invoice = nest2.id
GROUP BY id

澄清

感谢您提供任何具有改进版查询的帖子。当我开始尝试将嵌套转换为连接时,我正在处理一个产生意外结果的现有查询。我会继续玩它,但如果有人能回答关于聚合的问题以及为什么嵌套时必须重复它们,我也会非常感激。在 C# 中,我可以在一个函数中对三个数字求和,然后将结果值传回。我不必一直总结结果。我需要一些帮助来理解 SQL 子查询在这方面的不同功能。

可能的答案

我的一位同事指出,在这种情况下,这是因为我的GROUP BY条款。例如,由于cash_depositandjob_phase不在GROUP BY子句中,因此必须对它们进行聚合。

4

3 回答 3

1
SELECT i.id, SUM(i.cash_deposit), MAX(i.paid_off_date), MAX(j.job_phase), MAX(c.cust_id)
FROM invoice i
JOIN job j ON j.id = i.id
JOIN customer c ON c.invoice = i.id
GROUP BY id
于 2013-12-17T19:39:59.503 回答
1

它迫使您重新运行聚合,因为您在查询的每个步骤中都放置了 group by。如果您group by id从除最里面的查询之外的所有查询中删除,则不必重新进行聚合。

试着这样写:

SELECT id, cash_deposit, paid_off_date, job_phase, cust_id
FROM
(
    SELECT id AS id, SUM(cash_deposit) AS 'cash_deposit', MAX(paid_off_date) AS 'paid_off_date', job_phase
    FROM
    (
         SELECT id, cash_deposit, paid_off_date
         FROM invoice
         GROUP BY id
    ) nest1
    JOIN    job j
            ON nest1.id = j.id
) nest2
JOIN    customer c
        ON c.invoice = nest2.id

您现在也可以使用相同的确切结果集一步完成这两个联接,但我想向您展示所需的最少更改量。

于 2013-12-17T20:41:53.300 回答
0
select id, 
    sum(cash_deposit) as [cash_deposit],
    max(paid_off_date) as [paid_off_date],
    jp.[job_phase],
    cid.[cust_id]
from invoice i
cross apply (
    select max(job_phase) as [job_phase]
    from job j
    where j.id = i.id) jp
cross apply (
    select max(cust_id) as [cust_id]
    from customer c
    where i.id = c.invoice) cid
于 2013-12-17T20:55:38.960 回答