2

Server 2012 で次のスキーマとクエリを使用して、前年比の寄付レポートを作成しています。

CREATE TABLE Donation
(
   HouseholdID INT, 
   HouseholdName VARCHAR(150), 
   [Donation] REAL, 
   DateOrdered DATE
);

INSERT Donation VALUES
(1,'The Smiths',50,'2011-01-01'),
(1,'The Smiths',75,'2012-02-02'),
(2,'The Wilsons',10,'2011-03-01'),
(2,'The Wilsons',60,'2011-07-01'),
(3,'The Kellys',500,'2012-06-01');

--Params
DECLARE @RunYear   INT=2012
DECLARE @PriorYear INT=@RunYear-1

SELECT 
    [HouseholdID],[HouseholdName],YEAR(DateOrdered) [Year], MAX(Donation) [MaxGift], SUM(Donation) [TotalDonated]
FROM 
    Donation 
WHERE 
    YEAR([DateOrdered]) IN (@RunYear,@PriorYear)
    GROUP BY HouseholdID, [HouseholdName], YEAR(DateOrdered)
    ORDER BY HouseholdID, YEAR(DateOrdered)

[DonatedInPriorYearOnly] のような列を追加したいと思いBITます。これは、世帯が前年 (2011 年) に寄付を行ったが、実行年 (2012) に寄​​付がなかった場合にのみ 1 になります。

これはどのように達成できますか?

4

4 に答える 4

3

SQLServerのバージョンに応じて、サマリークエリを(サブクエリまたはCTEで)ラップしてLAGを使用できます。HouseholdIDとYearがLAGHouseholdIDと(Year-1)と一致しない場合、前年には寄付はありませんでした。

大まかにこのようなもの(テストされていない):

SELECT [HouseholdID], [HouseholdName], [Year], [MaxGift], [TotalDonated]
      ,CASE WHEN YEAR = previous_year +1 THEN 1 ELSE 0 END AS DonatedPreviousYear

   FROM ( SELECT [HouseholdID], [HouseholdName], [Year], [MaxGift], [TotalDonated]
                ,LAG(Year, 1, 0) OVER (PARTITION BY HouseholdID ORDER BY Year) AS previous_year

            FROM ( SELECT [HouseholdID],[HouseholdName],YEAR(DateOrdered) [Year], MAX(Donation) [MaxGift], SUM(Donation) [TotalDonated]
                     FROM  Donation 
                     WHERE [DateOrdered] BETWEEN @StartDt AND @EndDt
                     GROUP BY HouseholdID, [HouseholdName], YEAR(DateOrdered)
                     ORDER BY HouseholdID, YEAR(DateOrdered)
                  )
        )
于 2013-02-14T02:09:42.333 に答える
1
select blah, blah, blah
from donation
where householdid in 
(select householdid
from donation
where year(dateordered) = @runyear -1
except
select householdid
from donation
where year(dateordered) = @runyear )

それが論理です。より速く実行したい場合は、各年の最初と終わりに一致する一連の日付を作成し、 year(dateordered) の代わりにそれらを使用します

以下を編集

このロジックに基づいてビット列を作成するには、次のようにします。

select blah, blah, blah
, case 
when householdid in 
(select householdid
from donation
where year(dateordered) = @runyear -1
except
select householdid
from donation
where year(dateordered) = @runyear )
then 1 else 0 end nameofcolumn
from donation
where whatever
于 2013-02-14T03:30:57.717 に答える
1

色々な案を検討した結果、解決することができました。

[DonatedPriorYearOnly] = 
(
   CASE
   WHEN EXISTS 
   (
      SELECT HouseholdID FROM Donation d2
      WHERE YEAR(d2.DateOrdered)=@PriorYear AND d2.HouseholdID=d.HouseholdID
      EXCEPT
      SELECT HouseholdID FROM Donation d3 
      WHERE YEAR(d3.DateOrdered)=@RunYear AND d3.HouseholdID=d.HouseholdID

   )
   THEN 1 ELSE 0 END
)

回答ありがとうございます。それらはすべて役に立ちました。

于 2013-02-14T04:01:51.807 に答える
1

前年に各家族が行った寄付を検索OUTER APPLYするクエリを実行できます。SELECT TOP

SELECT 
     <your select list>
    ,ISNULL(lastyear.donated_bit,0) AS donated_last_year
FROM Donation AS d
OUTER APPLY(
    SELECT TOP 1 1 AS donated_bit
    FROM Donation AS d_lastyear
    WHERE d_lastyear.HouseholdID = d.HouseholdID
        AND DATEPART(year, d_lastyear.DateOrdered) = @RunYear - 1
        AND d_lastyear.Donation IS NOT NULL
        AND d_lastyear.Donation > 0
) AS lastyear
于 2013-02-14T02:40:16.903 に答える