意识到我之前提出的另一个问题可能太难了,我正在改变我的要求。
我在一家信用卡公司工作。我们的数据库有一个客户表和一个事务表。 customer表中的字段是SSN和CustomerKey。事务表中的字段是CustomerKey,事务日期(Transdate)和事务数量(TransAmt)。
我需要一个可以识别每个ssn的查询,其中任何交易金额的总和>如果ssn的交易金额> 1,则在2012年的两天内1000。在两天的时间内,我需要查询返回 所有 该ssn的交易。
以下是交易表中原始数据的示例:
Trans#-----CustKey-----Date--------Amount 1-----------12345----01/01/12--------$600 2-----------12345----01/02/12--------$500 3-----------67890----01/03/12--------$10 4-----------98765----04/01/12--------$600 5-----------43210----04/02/12--------$600 6-----------43210----04/03/12--------$100 7-----------13579----04/02/12--------$600 8-----------24568----04/03/12--------$100
以下是客户表中原始数据的示例:
CustKey-----SSN 12345------123456789 67890------123456789 98765------987654321 43210------987654321 13579------246801357 24568------246801357
以下是我需要的结果:
Trans#------SSN---------Date---------Amount 1--------123456789----01/01/12---------$600 2--------123456789----01/02/12---------$500 3--------123456789----01/03/12----------$10 4--------987654321----04/01/12---------$600 5--------987654321----04/02/12---------$600 6--------987654321----04/03/12---------$100
正如您在我的搜索结果中所看到的,包括SSN 123456789和987654321的 所有 交易,并排除了SSN 246801357。
答案 0 :(得分:1)
这样做的一种方法是在一年内每两天完成一次。这是一个 SQL Fiddle 示例。 这个想法非常简单:
1)创建临时表以存储所有匹配的客户
create table CustomersToShow
(
SSN int
)
2)循环一年,并使用符合金额标准的客户填充临时表
declare @firstDayOfTheYear datetime = '1/1/2012';
declare @lastDayOfTheYear datetime = '12/31/2012';
declare @currentDate datetime = @firstDayOfTheYear;
declare @amountThreshold money = 1000;
while @currentDate <= @lastDayOfTheYear
begin
insert into CustomersToShow(SSN)
select b.SSN
from transactions a
join customers b
on a.CustKey = b.CustKey
where TransactionDate >= @currentDate
and TransactionDate <= DATEADD(day, 2, @currentDate)
group by b.SSN
having SUM(a.TransactionAmount) >= @amountThreshold
set @currentDate = DATEADD(day,2,@currentDate)
end
3)然后选择
select a.TransNumber, b.SSN, a.TransactionDate, a.TransactionAmount
from transactions a
join customers b
on a.CustKey = b.CustKey
join CustomersToShow c
on b.SSN = c.SSN
注意:这会很慢......
答案 1 :(得分:0)
虽然您可能想出一种通过标准SQL来执行此操作的hacky方法,但这是一个问题,IMO更适合通过代码解决(即不是基于集合的逻辑/ SQL)。
如果按customerKey和date对事务列表进行排序,然后遍历数据,则很容易解决。理想情况下,我会在代码中执行此操作,但您也可以编写存储过程并使用循环和游标。
答案 2 :(得分:0)
如果您正确看待它,这很容易且非常适合基于集合的逻辑。您只需要加入一个包含您感兴趣的每个日期范围的表。每个T-SQL数据库(Oracle都内置它)应该有一个名为integers
的实用程序表 - 它经常令人惊讶地非常有用:
CREATE TABLE integers ( n smallint, constraint PK_integers primary key clustered (n))
INSERT integers select top 1000 row_number() over (order by o.id) from sysobjects o cross join sysobjects
您的日期表如下:
SELECT dateadd(day, n-1, '2012') AS dtFrom, dateadd(day, n+1, '2012') AS dtTo
from integers where n <= 366
然后你可以(缩写):
SELECT ssn, dtFrom
FROM yourTables t
JOIN ( SELECT dateadd(day, n-1, '2012') as dtFrom, dateadd(day, n+1, '2012') AS dtTo
from integers where n <= 366 ) d on t.date between d.dtFrom and d.dtTo
GROUP BY ssn, dtFrom
HAVING sum(amount) > 1000
您可以选择所有交易:
WHERE ssn in ( SELECT distinct ssn from ( <above query> ) t )