无需子选择即可查看查询 T-SQL

View query without sub selecting T-SQL

所以我正在尝试构建一个视图查询,但我一直失败,只使用连接,所以我最终得到了这种变形。关于如何编写这个查询的任何提示,这样我就不必使用 6 个子选择? FeeSum 和 PaymentSum 可以为空,因此理想情况下我不希望我的结果集中出现这些,我也不希望 FeeSum 和 PaymentSum 相等的结果。

快速说明:客户端是 table 存储客户端信息(名称、地址等)的地方 customer 在 client 上有一个 fk,有点像 shell table 为 client 存储更多信息, 付款是客户所做的所有付款的列表, order 是客户所做的所有订单的列表。

我们的目标是获得一个列表,我们可以在其中根据订单跟踪哪些客户需要支付未结费用。这是一个遗留项目,所以不要问为什么人们可以在付款前订购 :)

SELECT 
    cu.Id as [CustomerId]
    , CASE
        WHEN cl.IsPerson = 1
        THEN cl.[AdditionalName] + ' ' + cl.[Name]
        ELSE cl.AdditionalName
        END as [Name]
    , cl.CustomerNumber
    , (SELECT SUM(o.Fee) FROM [publication].[Order] o WHERE o.[State] = 2 AND o.CustomerId = cu.Id) as [FeeSum]
    , (SELECT SUM(p.Amount) FROM [publication].[Payment] p WHERE p.CustomerId = cu.Id) as [PaymentSum]
    , (SELECT MAX(o.OrderDate) FROM [publication].[Order] o WHERE o.[State] = 2 AND o.CustomerId = cu.Id) as [LastOrderDate]
    , (SELECT MAX(p.PaymentDate) FROM [publication].[Payment] p WHERE p.CustomerId = cu.Id) as [LastPaymentDate]
    , (SELECT MAX(f.Created) FROM [client].[File] f WHERE f.TemplateName = 'Reminder' AND f.ClientId = cl.Id) as [LastReminderDate]
    , (SELECT MAX(f.Created) FROM [client].[File] f WHERE f.TemplateName = 'Warning' AND f.ClientId = cl.Id) as [LastWarningDate]
FROM 
    [publication].[Customer] cu
JOIN
    [client].[Client] cl
    ON cl.Id = cu.ClientId
WHERE
    cu.[Type] = 0

提前致谢,希望我没有做错任何事。

亲切的问候

您可以重写相关子查询以改为使用连接:

SELECT
    cu.Id AS [CustomerId],
    CASE WHEN cl.IsPerson = 1
         THEN cl.[AdditionalName] + ' ' + cl.[Name]
         ELSE cl.AdditionalName END AS [Name],
    cl.CustomerNumber,
    o.FeeSum,
    p.PaymentSum,
    o.LastOrderDate,
    p.LastPaymentDate,
    f.LastReminderDate,
    f.LastWarningDate
FROM [publication].[Customer] cu
INNER JOIN [client].[Client] cl
    ON cl.Id = cu.ClientId
INNER JOIN
(
    SELECT CustomerId, SUM(Fee) AS [FeeSum], MAX(OrderDate) AS [LastOrderDate]
    FROM [publication].[Order]
    WHERE o.[State] = 2
    GROUP BY CustomerId
) o
    ON o.CustomerId = cu.Id
INNER JOIN
(
    SELECT CustomerId, SUM(Amount) AS [PaymentSum], MAX(PaymentDate) AS [LastPaymentDate]
    FROM [publication].[Payment]
    WHERE o.[State] = 2
    GROUP BY CustomerId
) p
    ON p.CustomerId = cu.Id
INNER JOIN
(
    SELECT ClientId,
           MAX(CASE WHEN TemplateName = 'Reminder' THEN Created END) AS [LastReminderDate],
           MAX(CASE WHEN TemplateName = 'Warning'  THEN Created END) AS [LastWarningDate]
    FROM [client].[File]
    GROUP BY ClientId
) f
    ON f.ClientId = cl.Id
WHERE
    cu.[Type] = 0;