一定时间内多笔交易,受日期范围限制

问题描述 投票:0回答:3

我有一个包含交易、人员、交易日期、物品等的数据库。 每次有人购买商品时,交易都会存储在表中,如下所示:

personNumber, TransactionNumber, TransactionDate, ItemNumber

我想要做的是找到从 2012 年 1 月 1 日(交易日期)到 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 天的限制应该放在哪里。我可以做一个约会,但是在哪里,通过什么?

sql sql-server sql-server-2005
3个回答
2
投票

唉,SQL Server 2005 中的窗口函数还不够强大。我将使用相关子查询来解决这个问题。

相关子查询计算一个人在每次购买后 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
投票

如果您的问题表明您只想查找具有指定条件的人员(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

0
投票

还需要考虑同一个人和物品的交易时间差。它可以按如下方式完成:

SELECT personNumber, TransactionNumber, TransactionDate, ItemNumber
FROM (
    SELECT 
        personNumber,
        transactionNumber,
        transactionDate,
        itemNumber,
        COUNT(*) OVER (
            PARTITION BY personNumber, itemNumber 
            ORDER BY transactionDate
            RANGE BETWEEN INTERVAL 14 DAY PRECEDING AND CURRENT ROW
        ) AS boughtSame
    FROM transactions
    WHERE transactionDate BETWEEN '2001-01-01' AND '2001-03-01'
) t
WHERE boughtSame > 1;
© www.soinside.com 2019 - 2024. All rights reserved.