识别余额等于零的记录

时间:2016-12-19 11:39:34

标签: postgresql

我有一个类似下面例子的表,有日期,数字,借方,贷方和余额(借方值+ 0 - 信用值),所以我想选择具有相同编号的记录,余额和是等于0然后识别这些记录。

我正在尝试创建一个函数,但我只在有两个相同记录的地方。在这个例子中,它是数字219900.在其他情况下,我不能。

我想在其他记录中做,这是在**之间。

date        num     debit   credit      balance   zero_balance
11/11/2016  219900          470,00      -470,00     Y
11/11/2016  219900  470,00              470,00      Y

01/11/2016  218295  163,00              163,00    
30/11/2016  218295  162,00              162,00      **Y**
30/11/2016  218295  162,00              162,00      **Y**
30/11/2016  218295          162,00      -162,00     **Y**
30/11/2016  218295          162,00      -162,00     **Y**
30/11/2016  218295  162,00              162,00  

25/10/2016  218102  935,46              935,46      **Y**
25/10/2016  218102          935,46      -935,46     **Y**
25/10/2016  218102  935,46              935,46

20/10/2016  217638  1.896,65            1.896,65    **Y**   
20/10/2016  217638          1.896,65    -1.896,65   **Y**   
20/10/2016  217638  1.896,65            1.896,65    **Y**   
20/10/2016  217638          1.896,65    -1.896,65   **Y**   
20/10/2016  217638  1.696,65            1.696,65    

有人能帮帮我吗?

2 个答案:

答案 0 :(得分:1)

我会打电话给你的桌子t(在你的查询中使用你自己的名字)。另外,我根本不会使用balance字段;它似乎是多余的(但答案也适用于该栏目。)

如果您有主键,则只需为每个num的点数和借方提供一个索引(cd_idx以下)。您可以使用该索引搜索对。

with d as (
  select t r, row_number() over (partition by num, credit, debit order by date, id) cd_idx
  from t
)
select    (d1.r).*, (d2.r).id is not null zero_balance
from      d d1
left join d d2 on (d1.r).id <> (d2.r).id
and       (d1.r).num = (d2.r).num
and       d1.cd_idx = d2.cd_idx
and       ((d1.r).credit = (d2.r).debit or (d1.r).debit = (d2.r).credit)
order by  (d1.r).id

请注意,cd_idx是按num, credit, debit的升序为相同的date, id元组生成的r。另请注意,我将整行放入(d1.r).*列,但如果您只想选择特定列,则不必如此(这样我就可以轻松选择所有属性 row_number()的那一行。

如果您没有主键,可以使用with t as (select *, row_number() over () id from t), d as ( select t r, row_number() over (partition by num, credit, debit order by date, id) cd_idx from t ) select (d1.r).*, (d2.r).id is not null zero_balance from d d1 left join d d2 on (d1.r).id <> (d2.r).id and (d1.r).num = (d2.r).num and d1.cd_idx = d2.cd_idx and ((d1.r).credit = (d2.r).debit or (d1.r).debit = (d2.r).credit) order by (d1.r).id 暂时生成一个主键,但这样就不能保证多次执行会得到相同的结果。

  return DB::table('container_slots')
->where('occupied', false)
->join('plate_containers','container_slots.plate_container_id', '=', 'plate_containers.id')
->select('plate_containers.name AS Container', DB::raw('count(container_slots.slot) as no_of_slots'))
->groupBy('plate_container_id')->get();

Rextester

答案 1 :(得分:0)

使用窗口功能 https://www.postgresql.org/docs/current/static/tutorial-window.html 我认为它应该对你有帮助。

select
    date
    ,num
    ,debit
    ,credit
    ,sum(debit) over (partition by num) as sum_deb
    ,sum(credit) over (partition by num) as sum_cred
    ,case when
         sum(debit) over (partition by num) = sum(credit) over (partition by num)
         then 'Y' else 'N' end as zero_balance
from test_debt