2

私はこれに似たテーブルデータ構造を持っています:

家主テーブル

Id    Name        Email
```````````````````````
1     J Johnson    ...
2     R Kelly      ...

プロパティテーブル

Id    Address    Rent    LandlordId
```````````````````````````````````
1    ....        400    1
2    ....        600    1
3    ....        750    2

メンテナンステーブル

Id    Details   Cost    MaintenanceDate    PropertyId
`````````````````````````````````````````````````````
1    ....        25     20/12/2012         1
2    ....        120    22/12/2012         2
3    ....        35     24/12/2012         3

基本的に、家主には複数の物件があります。毎月、家主のすべての物件と、その物件で行われたすべてのメンテナンスを含む請求書を作成する必要があります。家主に支払う必要のある金額を計算するには、家主のすべての物件の家賃を合計し、その月のすべての維持費の合計からそれを差し引く必要があります。

したがって、家主に支払う金額L = Sum(Lの物件の賃貸料)-Sum(今月の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

複数のフィールドが生成されるため、これは正しく機能していないようです

レポートをサブレポートに分割するので、最初に家主の詳細を取得するだけだと思いましたが、この場合でも家主に支払う金額を計算する必要があります。そこで、クエリを次のように書き直しました。

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

これは問題なく機能したと思いましたが、distinctを使用したにもかかわらず、これによりPayableToLandlord量が異なる重複行が生成されるようで、理由がわかりません。

すべての家主、その物件、および家主に支払う金額を1つのクエリで選択する方法はありますか?

ここでは、わかりやすくするために、datewhere句を削除しました。

ありがとう。

4

3 に答える 3

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

あなたも書いたことに気づきました:

すべての家主、その物件、および家主に支払う金額を1つのクエリで選択する方法はありますか?

プロパティのリストにさらに参加することもできますが、最終的には各行で合計を繰り返すことになります。レポートパッケージ内で合計しようとしない限り、これは問題ありません。

プロパティの詳細が必要な場合は、各プロパティの家賃と費用を取得してから、レポートパッケージのSUM/ネットの数値を取得することをお勧めします。

于 2012-12-24T17:18:56.813 に答える
1

短いクエリは次のとおりです。コメントしてください。

select l.name, x.propid,
sum(x.tot) as finalrent
from landlord l
left join
(select p.landlordid, (p.rent - m.cost) as tot,
p.id as propid 
from property p left join 
maintenance m
on p.id = m.propertyid) as x
on
l.id = x.landlordid
group by l.id, x.propid
;


NAME        PROPID  FINALRENT
J Johnson   1       375
J Johnson   2       480
R Kelly     3       715

2012年12月25日


編集してSQLFIDDLEと結果を追加しますgroup by landlord only

クエリには、費用を差し引いた後の総家賃が表示されます。

クエリ:

-- group by landlord only

select l.id, l.name,
sum(x.tot) as finalrent, 
sum(COALESCE(x.cost,0)) as TotalCost
from landlord l
left join
(select p.landlordid, 
(p.rent - COALESCE(m.cost,0)) as tot,
p.id as propid, m.cost 
from property p left join 
maintenance m
on p.id = m.propertyid) as x
on l.id = x.landlordid
group by l.id
;

結果:

ID  NAME        FINALRENT   TOTALCOST
1   R Johnson   880         120
2   R Kelly     715         35

2012年12月27日

于 2012-12-24T18:23:14.100 に答える
0

ジョエルの答えはとても良いです。ただし、これを表現するためのやや簡単な方法があります。物件レベルでサブクエリで要約を行い、次に外部クエリで家主レベルで要約することができます。

SELECT l.Id as LandlordId, l.Name, 
       sum(p.rent) as TotalRent,
       coalesce(sum(p.rent), 0) AS TotalRent, 
       coalesce(sum(m.PropertyCost), 0) AS TotalCost
FROM Landlord l left outer join
     Property p
     on l.LandlordId = p.LandlordId left outer join
     (SELECT PropertyId, SUM(Cost) AS PropertyCost
      FROM Maintenance m
      group by PropertyId
     ) m
     on m.PropertyId = p.PropertyId
group by l.LandLordId, l.LandlordName
ORDER BY Landlord.Name

これにより、2番目のサブクエリの結合が保存されます。

于 2012-12-24T18:20:17.897 に答える