1

トランザクション、人、トランザクションの日付、アイテムなどのデータベースがあります。人がアイテムを購入するたびに、トランザクションは次のようにテーブルに保存されます。

personNumber, TransactionNumber, TransactionDate, ItemNumber

私がやりたいのは、2012年1月1日(transactionDate)から2012年3月1日までに同じItemNumberを14日以内(構成可能)以内に複数回購入した人(personNumber)を見つけることです。次に、これらすべてのトランザクションをレポートにリストする必要があります。

サンプルデータ:

personNumber, TransactionNumber, TransactionDate, ItemNumber
1           |               100|      2001-01-31|        200
2           |               101|      2001-02-01|        206
2           |               102|      2001-02-11|        300
1           |               103|      2001-02-09|        200
3           |               104|      2001-01-01|        001
1           |               105|      2001-02-10|        200
3           |               106|      2001-01-03|        001
1           |               107|      2001-02-28|        200

結果:

personNumber, TransactionNumber, TransactionDate, ItemNumber
1           |               100|      2001-01-31|        200
1           |               103|      2001-02-09|        200
1           |               105|      2001-02-10|        200
3           |               104|      2001-01-01|        001
3           |               106|      2001-01-03|        001

どうやってそれをやりますか?

私はそのようにそれをやってみました:

select * 
from (
    select personNumber, transactionNumber, transactionDate, itemNumber,
count(*) over (
    partition by personNumber, itemNumber) as boughtSame)
from transactions
where transactionDate between '2001-01-01' and '2001-03-01')t
where boughtSame > 1

そしてそれは私にこれを与えます:

personNumber, TransactionNumber, TransactionDate, ItemNumber
1           |               100|      2001-01-31|        200
1           |               103|      2001-02-09|        200
1           |               105|      2001-02-10|        200
1           |               107|      2001-02-28|        200
3           |               104|      2001-01-01|        001
3           |               106|      2001-01-03|        001

問題は、14日以内ではないため、TransactionNumber107が不要なことです。その14日の制限をどこに置くべきかわかりません。私はdatediffを行うことができましたが、どこで、何を超えていますか?

4

2 に答える 2

2

残念ながら、SQLServer2005のウィンドウ関数は十分に強力ではありません。相関サブクエリを使用してこれを解決します。

相関サブクエリは、各購入後14日以内に人がアイテムを購入した回数をカウントします(最初の購入はカウントしません)。

select t.*
from (select t.*,
             (select count(*)
              from t t2
              where t2.personnumber = t.personnumber and
                    t2.itemnumber = t.itemnumber and
                    t2.transactionnumber <> t.transactionnumber and
                    t2.transactiondate >= t.transactiondate and 
                    t2.transactiondate < DATEADD(day, 14, t.transactiondate
             ) NumWithin14Days
      from transactions t
      where transactionDate between '2001-01-01' and '2001-03-01'
     ) t
where NumWithin14Days > 0

サブクエリにも時間制限を設定することをお勧めします。

のインデックスtransactions(personnumber, itemnumber, transactionnumber, itemdate)は、これをはるかに高速に実行するのに役立つ可能性があります。

于 2013-02-27T22:44:07.653 に答える
1

質問に、指定された基準で人(personNumbers)を見つけたいだけの場合は、自己結合を実行して、次のようにグループ化できます。

create table #tx (personNumber int, transactionNumber int, transactionDate dateTime, itemNumber int)
insert into #tx
values
    (1, 100, '2001-01-31', 200),
    (2, 101, '2001-02-01', 206),
    (2, 102, '2001-02-11', 300),
    (1, 103, '2001-02-09', 200),
    (3, 104, '2001-01-01', 001),
    (1, 105, '2001-02-10', 200),
    (3, 106, '2001-01-03', 001),
    (1, 107, '2001-02-28', 200)

declare @days int = 14

select t1.personNumber from #tx t1 inner join #tx t2 on 
    t1.personNumber = t2.personNumber 
    and t1.itemNumber = t2.itemNumber
    and t1.transactionNumber < t2.transactionNumber
    and datediff(day, t1.transactionDate, t2.transactionDate) between 0 and @days
group by t1.personNumber
-- if more than zero joined rows there is more than one transaction in period
having count(t1.personNumber) > 0 

drop table #tx
于 2013-02-27T22:48:41.377 に答える