我有一个交易,人员,交易日期,项目等的数据库。 每次人们购买物品时,交易都会存储在表格中,如下所示:
personNumber, TransactionNumber, TransactionDate, ItemNumber
我想要做的是找到从2012年1月1日(transactionDate)到2012年3月1日在14天内(可配置)或更少时间内多次购买相同ItemNumber的人(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
问题是我不想要TransactionNumber 107,因为那不是14天之内。我不确定在14天的限制内放在哪里。我可以做一个约会,但在哪里,在什么地方?
答案 0 :(得分:1)
相关子查询计算每次购买后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)
上的索引可能会更快地运行。
答案 1 :(得分: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