1

まず、これは 2010 年の支出額上位 20% を見つけたものです。

select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
    count(o.OrderID) as TotalOrders
from dbo.tblOrder o with (nolock)
where o.DomainProjectID=13
    and o.BillEmail not like ''
    and o.OrderDate >= '2010-01-01'
    and o.OrderDate < '2011-01-01'
group by o.BillEmail
order by TotalSpent desc

これから、上位 20% の消費者の今後 2 年間の継続率を求める必要があります。

つまり、2010 年の上位 20% のうち、2011 年、そして 2012 年にも首位に立っているのはどれでしょうか? 注: 2010 年、次に 2011 年、そして 2012 年に何人いたかを数える必要があります。

別のテーブルを作成するか、上位のバイヤーのみをリストした Excel シートから取得できれば、はるかに簡単になることはわかっています。ただし、データベースへの書き込みアクセス権がないため、ネストされたクエリですべてを実行するか、提案する必要があります。私はまだ初心者なので、最善の方法がわかりません。

ありがとうございました!

4

5 に答える 5

4

興味深い質問があります。基本的に、それはある年から次の年への支出の五分位数の移行に関するものです。これを解決するには、3 年間のすべての五分位数を調べて、人々がどこに移動するかを確認します。

これは、年別および電子メール別のデータの要約から始まります。キー機能はntile(). 正直なところ、私は頻繁にrow_number()andを使って自分で計算を行いますcount()。そのため、それらは CTE に含まれています (ただし、その後は使用されません)。

with YearSummary as (
      select year(OrderDate) as yr, o.BillEmail, SUM(o.total) as TotalSpent,
             count(o.OrderID) as TotalOrders,
             row_number() over (partition by year(OrderDate) order by sum(o.Total) desc) as seqnum,
             count(*) over (partition by year(OrderDate)) as NumInYear,
             ntile(5) over (partition by year(OrderDate) order by sum(o.Total) desc) as Quintile
      from dbo.tblOrder o with (nolock)
      where o.DomainProjectID=13 and o.BillEmail not like ''
      group by o.BillEmail, year(OrderDate)
     )
select q2010, q2011, q2012,
       count(*) as NumEmails,
       min(BillEmail), max(BillEmail)
from (select BillEmail,
             max(case when yr = 2010 then Quintile end) as q2010,
             max(case when yr = 2011 then Quintile end) as q2011,
             max(case when yr = 2012 then Quintile end) as q2012
      from YearSummary
      group by BillEmail
     ) ys
group by q2010, q2011, q2012
order by 1, 2, 3;

最後のステップは、各電子メールの複数の行を取得し、それらをカウントに結合することです。一部の電子メールは特定の年に支出がないため、対応Quintileするものは NULL になることに注意してください (これは実際には 125 行 - 5*5*5 ではなく、180 行 - 5*6*6 のようになります)

また、最終結果 (min()およびmax()) にサンプル メールを含めて、各グループのサンプルを確認できるようにします。

注: 保持率については、(1, 1, 1) -- すべての年の上位タイル -- と 2010 年の上位 5 分位の合計との比率を計算します。

于 2013-08-05T15:32:40.527 に答える
0
SELECT Base2010.BillEmail, 
CASE WHEN retention2011.BillEmail = '' THEN 'Not retained' ELSE 'Retained' END AS retained2011, 
CASE WHEN retention2012.BillEmail = '' THEN 'Not retained' ELSE 'Retained' END AS retained2012
FROM 
    (select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders, BillEmail
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2010-01-01'
        and o.OrderDate < '2011-01-01'
    group by o.BillEmail
    ) AS Base2010

LEFT JOIN
    (select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders, BillEmail 
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2011-01-01'
        and o.OrderDate < '2012-01-01'
    group by o.BillEmail
    ) AS retention2011
ON Base2010.BillEmail = retention2011.BillEmail

LEFT JOIN
    (select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders, BillEmail
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2012-01-01'
        and o.OrderDate < '2013-01-01'
    group by o.BillEmail
    ) AS retention2012
ON Base2010.BillEmail = retention2012.BillEmail
于 2013-08-05T15:23:35.770 に答える
0

個人的には、いくつかの CTE を使用します。年に1つ。また、私は物事にもう少し一般的な名前を付けたいと思います (あらゆる場所に年の名前を埋め込むのではなく)。結果セットを取得したらEXISTS、3 つの期間すべてに誰がいたかを確認するために使用できます。

-- Get the 1st Jan in the  current year
DECLARE @current_year date = DateAdd(yy, DateDiff(yy, 0, Current_Timestamp), 0);

; WITH highest_spenders_2_years_ago AS (
  <your_query>
  WHERE  o.orderDate >= DateAdd(yy, -2, @current_year)
  AND    o.orderDate <  DateAdd(yy, -1, @current_year)
)
, highest_spenders_last_year AS (
  <your_query>
  WHERE  o.orderDate >= DateAdd(yy, -1, @current_year)
  AND    o.orderDate <  DateAdd(yy,  0, @current_year)
)
, highest_spenders_this_year AS (
  <your_query>
  WHERE  o.orderDate >= DateAdd(yy,  0, @current_year)
  AND    o.orderDate <  DateAdd(yy,  1, @current_year)
)
SELECT *
FROM   highest_spenders_this_year
WHERE  EXISTS (
         SELECT *
         FROM   highest_spenders_last_year
         WHERE  BillEmail = highest_spenders_this_year.BillEmail
       )
AND    EXISTS (
         SELECT *
         FROM   highest_spenders_2_years_ago
         WHERE  BillEmail = highest_spenders_this_year.BillEmail
       )
于 2013-08-05T15:20:54.547 に答える
0

これを試して:

;WITH top_2010 AS 
(
    select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2010-01-01'
        and o.OrderDate < '2011-01-01'
    group by o.BillEmail
), 
top_2011 AS 
(
    select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2011-01-01'
        and o.OrderDate < '2012-01-01'
    group by o.BillEmail
), 
top_2012 AS 
(
    select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
        count(o.OrderID) as TotalOrders
    from dbo.tblOrder o with (nolock)
    where o.DomainProjectID=13
        and o.BillEmail not like ''
        and o.OrderDate >= '2012-01-01'
        and o.OrderDate < '2013-01-01'
    group by o.BillEmail
)
SELECT top_2010.*, 
    ISNULL(top_2011.TotalSpent, 0) AS [TotalSpent_2011],ISNULL(top_2011.TotalOrders, 0) AS [TotalOrders_2011] ,
    ISNULL(top_2012.TotalSpent, 0) AS [TotalSpent_2012],ISNULL(top_2012.TotalOrders, 0) AS [TotalOrders_2012]
FROM top_2010
LEFT JOIN top_2011 ON top_2010.BillEmail = top_2011.BillEmail 
LEFT JOIN top_2012 ON top_2010.BillEmail = top_2012.BillEmail 
WHERE top_2011.BillEmail IS NOT NULL OR top_2012.BillEmail IS NOT NULL
order by top_2010.TotalSpent desc

2011年または2012年LEFT JOINのトップにあったものをすべて見ることができるように、私が使用していることに注意してください

2011年と2012年にあったものが必要な場合は、に変更できますINNER JOIN

于 2013-08-05T15:19:44.507 に答える
0

これを行うには、共通テーブル式を使用できます。各年の上位 20% のリストを作成し、それらを内部結合して、3 年間すべてで上位 5 分位にある企業を見つけます。3 年すべてに存在するレコードのみが必要なため、左結合は使用しないでください。

WITH Top2010 AS (
select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
    count(o.OrderID) as TotalOrders
from dbo.tblOrder o with (nolock)
where o.DomainProjectID=13
    and o.BillEmail not like ''
    and o.OrderDate >= '2010-01-01'
    and o.OrderDate < '2011-01-01'
group by o.BillEmail
order by TotalSpent desc
),
Top2011 AS (
select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
    count(o.OrderID) as TotalOrders
from dbo.tblOrder o with (nolock)
where o.DomainProjectID=13
    and o.BillEmail not like ''
    and o.OrderDate >= '2011-01-01'
    and o.OrderDate < '2012-01-01'
group by o.BillEmail
order by TotalSpent desc
),
Top2012 AS (
select top (20)percent o.BillEmail,SUM(o.total) as TotalSpent,
    count(o.OrderID) as TotalOrders
from dbo.tblOrder o with (nolock)
where o.DomainProjectID=13
    and o.BillEmail not like ''
    and o.OrderDate >= '2012-01-01'
    and o.OrderDate < '2013-01-01'
group by o.BillEmail
order by TotalSpent desc
)

SELECT Top2010.BillEmail -- plus whatever other columns you want
FROM Top2010
INNER JOIN Top2011 ON Top2010.BillEmail = Top2011.BillEmail
INNER JOIN Top2012 ON Top2012.BillEmail = Top2011.BillEmail
于 2013-08-05T15:19:57.573 に答える