【问题标题】:Identify repeating raws (loans) in sql识别 sql 中重复的 raws(贷款)
【发布时间】:2017-03-20 15:45:07
【问题描述】:

我有一张这样的桌子:

Client  Branch  Amount  Date
1        2      1500    1.1.14
1        2      1400    3.1.14
1        3      1500    1.1.14
1        4      300     7.1.14
1        5      1500    1.1.14
------------------------------
2        2      300     1.1.14
2        2      300     1.1.14
2        5      300     1.1.14
2        3      400     4.1.14
------------------------------           
3        2      300     1.1.14
3        2      300     1.1.14
3        5      300     1.1.14
3        5      300     1.1.14
3        3      400     4.1.14
4        2      300     1.1.14  
4        2      300     1.1.14 
4        5      300     1.1.14 
4        5      300     1.1.14  
4        5      300     1.1.14 

我想要的输出应该是这样的:

   Client   Branch  Amount  Date   Ind  Loan_Distinct_Num
    1        2      1500    1.1.14  0         1
    1        2      1400    3.1.14  0         2 
    1        3      1500    1.1.14  1         1
    1        4      300     7.1.14  0         3
    1        5      1500    1.1.14  1         1
    -------------------------------------------------
    2        2      300     1.1.14  0         1
    2        2      300     1.1.14  0         2
    2        5      300     1.1.14  1         2
    2        3      400     4.1.14  0         3
    --------------------------------------------------           
    3        2      300     1.1.14  0         1
    3        2      300     1.1.14  0         2 
    3        5      300     1.1.14  1         1
    3        5      300     1.1.14  1         2
    3        3      400     4.1.14  0         3
    ------------------------------------------------     
    4        2      300     1.1.14  0         1
    4        2      300     1.1.14  0         2
    4        5      300     1.1.14  1         1
    4        5      300     1.1.14  1         2
    4        5      300     1.1.14  0         3

那我想做什么? (注释:那些记录只是一个样本数据)

嗯,这些是规则: 客户从同一家银行的一个分行搬到另一个分行。问题是分支机构多次为他写入数据。我想确定重复的贷款。需要两个步骤:

第 1 步: 假设:Same_Amount + Same_Date + Diffrent Date ---> Ind = 1 在第一个 raw 之后的记录上。

Ind 字段如何工作?

例如: 在客户端 = 1 的分区中,数量 1500 对相同日期和不同分支重复 3 次,但只有最后两个此详细信息的记录将为 Ind 获得“1”值,第一个将获得 Ind = 0,因为它不是重复贷款,数据中首次出现该金额和日期的记录。

如果像 client = 2 一样,branch = 2 有两条记录,branch = 5 只有一条记录,所以在这种情况下,我将假设 branch = 2 的最后一条记录正在重复。

如果客户 = 3,分支 = 2 中有两条记录,分支 = 5 有两条记录,所以在这种情况下,我将假设来自分支 2 的两笔贷款都重复了。

如果客户 = 4,那么它将与客户 3 相同,但还有另一条记录,但我会认为它是新记录,因为我没有多余的过去贷款可以与她交流。

第 2 步:我想为每个客户创建自己的不同贷款编号

对如何接近解决这个不简单的问题有任何帮助吗?

评论:sql-server 2008.

【问题讨论】:

  • Row_Number 适用于 client = 1 的情况。那么客户端 = 2,3,4 呢?
  • 这些记录是否按创建时间顺序排列?对于客户端 1,你怎么知道 1 / 2 / 1500 / 1.1.14 发生在 1 / 3 / 1500 / 1.1.14 或 1 / 5 / 1500 / 1.1.14 之前?
  • 是的。假设数据排序正确。

标签: sql sql-server case rank


【解决方案1】:

首先 - 将您的数据设置到表格中。我添加了一个标识列 ID,因此我们有一些东西要订购 - 您在评论中指定您的数据按特定顺序排列。

declare @data table (ID int identity(1,1), Client int, Branch int, Amount int, [Date] date);
insert into @data values
(1,2,  1500,'2014-01-01'),
(1,2,  1400,'2014-03-01'),
(1,3,  1500,'2014-01-01'),
(1,4,  300,'2014-07-01'),
(1,5,  1500,'2014-01-01'),
(2,2,  300,'2014-01-01'),
(2,2,  300,'2014-01-01'),
(2,5,  300,'2014-01-01'),
(2,3,  400,'2014-04-01'),
(3,2,  300,'2014-01-01'),
(3,2,  300,'2014-01-01'),
(3,5,  300,'2014-01-01'),
(3,5,  300,'2014-01-01'),
(3,3,  400,'2014-04-01'),
(4,2,  300,'2014-01-01'),
(4,2,  300,'2014-01-01'),
(4,5,  300,'2014-01-01'),
(4,5,  300,'2014-01-01'),
(4,5,  300,'2014-01-01');

这里是我们进行查询的地方:

--In the first cte, we take all the data, and partition it up into individual loans (partition by Client, Amount, Date).
with cte1 as (
    select *, ROW_NUMBER() over (partition by Client, Amount, Date order by ID) as rowno from @data
), cte2 as (
    --in this cte, we get a list of distinct loans. We will use another rownumber in a bit to find our Loan_Distinct_Num
    select distinct Client, Amount, [Date] from @data
)
select cte1.Client, cte1.Branch, cte1.Amount, cte1.[Date]
      -- If rowno = 1, it's the first instance of that combination
    , case when rowno = 1 then 0 else 1 end as ind
    , b.Loan_Distinct_Num
 from cte1
 left join (select cte2.*, ROW_NUMBER() over (partition by Client order by [Date]) as Loan_Distinct_Num
             -- This is where our distinct loan number comes from
              from cte2 
              ) as b
              on b.Client = cte1.Client and b.Amount = cte1.Amount and b.[Date] = cte1.[Date]
 order by ID

【讨论】:

  • 有什么方法可以让进程运行得更快?我正在尝试在 250 万客户上运行它。 1 天过去了,进程仍在运行。
  • 在桌子上放一个索引。
【解决方案2】:

如果存在具有不同分支 # 的先前记录,则 ind 应仅为 1,这是一个答案(请参见第 7 行)。此外,使用dense_rank 在loan_distinct_num 中按金额/日期对贷款进行分组。该列的逻辑似乎更复杂 - 如果这是一次性修复,我可能会使用游标循环遍历表并应用一些更复杂的逻辑来填充该列,而不是尝试在查询中计算它。

-- sample data
declare @data table (ID int identity(1,1), Client int, Branch int, Amount int, [Date] date);
insert into @data values
(1,2,  1500,'2014-01-01'),
(1,2,  1400,'2014-03-01'),
(1,3,  1500,'2014-01-01'),
(1,4,  300,'2014-07-01'),
(1,5,  1500,'2014-01-01'),
(2,2,  300,'2014-01-01'),
(2,2,  300,'2014-01-01'),
(2,5,  300,'2014-01-01'),
(2,3,  400,'2014-04-01'),
(3,2,  300,'2014-01-01'),
(3,2,  300,'2014-01-01'),
(3,5,  300,'2014-01-01'),
(3,5,  300,'2014-01-01'),
(3,3,  400,'2014-04-01'),
(4,2,  300,'2014-01-01'),
(4,2,  300,'2014-01-01'),
(4,5,  300,'2014-01-01'),
(4,5,  300,'2014-01-01'),
(4,5,  300,'2014-01-01');

-- query
select client, branch, amount, date, 
    case when exists (select * from @data t2 where client = tbl.client and branch <> tbl.branch and amount = tbl.amount and date = tbl.date and id < tbl.id) then 1 else 0 end as ind,
    DENSE_RANK() over (partition by client order by date, amount asc) as loan_disinct_num
from @data tbl
order by id;

【讨论】:

  • 谢谢。没有dense_rank的任何方法?因为我正在使用 sqldf (sqllite)。
  • select client, branch, amount, date, (select count(*) from ( select distinct amount, date from @data where client = tbl.Client and (date &lt; tbl.Date or (date = tbl.date and amount &lt; tbl.Amount)) )sq ) + 1 as dense_rank_different_approach from @data tbl order by id; - 这应该等同于使用 count 和 distinct 的 dense_rank
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-07
  • 2015-05-04
相关资源
最近更新 更多