复杂的SQL查询 - 选择所有房东的属性并在一个查询中减去成本

Ale*_*der 2 sql t-sql sql-server-2008

我有一个类似于这样的表数据结构:

楼主表

Id    Name        Email
```````````````````````
1     J Johnson    ...
2     R Kelly      ...
Run Code Online (Sandbox Code Playgroud)

属性表

Id    Address    Rent    LandlordId
```````````````````````````````````
1    ....        400    1
2    ....        600    1
3    ....        750    2
Run Code Online (Sandbox Code Playgroud)

维护表

Id    Details   Cost    MaintenanceDate    PropertyId
`````````````````````````````````````````````````````
1    ....        25     20/12/2012         1
2    ....        120    22/12/2012         2
3    ....        35     24/12/2012         3
Run Code Online (Sandbox Code Playgroud)

从本质上讲,房东有多个房产..每个月,我需要为房东制作一张发票,其中包括他的所有房产,以及他所有房产的所有维修费用.为了计算我需要向房东支付多少钱,我需要将他所有的房产"租金"加起来并用该月所有维护费用的总和减去.

因此,应付给房东的金额L =总和(L的物业租金) - 总和(本月L所有物业的维护费用)

我正在使用telerik报告,认为我可以通过一些聪明的分组实现它,但这是浪费我的时间所以我现在将尝试用SQL和子报告来实现这一点.

我正在尝试的SQL查询是这样的:

 SELECT l.Name, p.[Address], p.Rent, c.Details, c.Cost,
(select Rent From Property where Id = p.Id) - 
    (select SUM(cost) from CarriedOutJobs where PropertyId = p.Id) 
    as PayableToLandlord
FROM Landlord l JOIN PROPERTY p ON p.LandlordId = l.Id
LEFT OUTER JOIN Maintenance c ON c.PropertyId = p.Id
ORDER BY l.Fullname
Run Code Online (Sandbox Code Playgroud)

这似乎不能正常工作,因为它会产生多个字段

因为我要将报告拆分成子报告,我想我会先得到房东的详细信息,但我仍然需要计算应付给房东的金额,即使在这种情况下.所以我把查询重写为:

SELECT distinct l.Name,
(SELECT SUM(Rent) FROM PROPERTY WHERE LandlordId = l.Id) - 
    (SELECT COALESCE(SUM(cost), 0)
    FROM CarriedOutJobs WHERE PropertyId = p.Id) AS     PayableToLandlord
FROM Landlord l 
JOIN PROPERTY p ON p.LandlordId = l.Id 
ORDER BY l.Fullname
Run Code Online (Sandbox Code Playgroud)

我认为这样做没问题,但即使我使用了不同的,这似乎产生了一个不同PayableToLandlord数量的重复行,我似乎无法弄清楚为什么.

有没有办法在一个查询中选择所有房东,他们的房产以及应付给他们的金额,好吗?

为了简单起见,我在这里删除了date where子句.

谢谢.

Joe*_*ord 6

我建议保持简单并使用子查询,因为这些很容易解决正在发生的事情.希望您可以在报告中进行减法等,或者仅仅作为额外的返回列.您应该将任何日期参数作为变量传入子查询(可能).

SELECT Landlord.Id as LandlordId, Landlord.Name, 
       ISNULL(TotalRent,0) AS TotalRent, 
       ISNULL(TotalCost,0) AS TotalCost
FROM Landlord
LEFT JOIN 
    (SELECT SUM(Rent) as TotalRent, LandLordId 
     FROM Property
     GROUP BY LandLordId) Rents
ON Landlord.Id = Rents.LandlordId
LEFT JOIN 
    (SELECT LandLordId,SUM(Cost) AS TotalCost
     FROM Property
     INNER JOIN Maintenance
        ON Property.Id = Maintenance.PropertyId
     GROUP BY LandLordId
     ) MaintenanceCosts
ON Landlord.Id = MaintenanceCosts.LandlordId
ORDER BY Landlord.Name
Run Code Online (Sandbox Code Playgroud)

刚注意到你还写道:

有没有办法在一个查询中选择所有房东,他们的房产以及应付给他们的金额,好吗?

您可以进一步加入属性列表,但最终会在每一行上重复总和.只要您不在报告包中尝试将其汇总,这就没问题.

如果您确实需要房产详细信息,那么我的建议是提取每个房产租金和成本,然后在报告包中进行SUM /净数字.