Sql 自联接表并仅使用行一次-正确使用稠密的_秩()

Sql 自联接表并仅使用行一次-正确使用稠密的_秩(),sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,首先,一些虚构的数据: create table #testm ( transdate date, item nvarchar(20), qty int, whse nvarchar(10), loc nvarchar(10) ) insert into #testm (transdate, item, qty, whse, loc) values ('20180601', '123', 100, 'main', 'qc'), ('20180

首先,一些虚构的数据:

create table #testm
(
    transdate date,
    item nvarchar(20),
    qty int,
    whse nvarchar(10),
    loc nvarchar(10)
)
insert into #testm (transdate, item, qty, whse, loc)
values ('20180601', '123', 100, 'main', 'qc'),
       ('20180602', '123', -100, 'main', 'qc'), 
       ('20180603', '123', 100, 'main', 'qc'),
       ('20180604', '123', -100, 'main', 'qc'), 
       ('20180602', '1234', 100, 'main', 'qc'), 
       ('20180602', '1234', -100, 'main', 'notqc')
情景: 我有一个表格,记录我的所有交易,如股票移动和其他。我需要生成一个报告,它将在testm表字段中显示输入特定loc的项目的数据,然后退出它。但是,我只需要对每个出口计数一次,这样它就不会将自己连接到与项目和数量匹配的每个其他入口。然后,我需要看看该物品在loc中花费了多少时间。特殊情况是当物品还没有离开loc时,它应该在quesry的第二部分中显示空值,并从getdate开始使用datediff

在上面的insert语句中,预期结果是将第1行与第2行匹配,第3行与第4行匹配,第5行与第5行匹配,因为还没有退出,第6行的loc不正确,跳过第6行,因为loc不是我要查找的

结果应该是这样的

     transdate  item qty whse loc td2        it2  qt2   wh2     lo2 datediffhour
     2018-06-01 123  100 main qc  2018-06-02 123  -100  main    qc   24
     2018-06-02 1234 100 main qc  NULL       NULL NULL  NULL    NULL 1056
     2018-06-03 123  100 main qc  2018-06-04 123  -100  main    qc   24
以下是我的尝试:

select * from
(
    select tin.transdate, tin.item, tin.qty, tin.whse, tin.loc, DENSE_RANK() over(partition by tin.transdate order by tout.transdate) as firstrank,
    DENSE_RANK() over (partition by tout.transdate order by tin.item) as secondrank, tout.transdate as td2, tout.item as it2, tout.qty as qt2, tout.whse as wh2, tout.loc as lo2,
    datediff(hour, tin.transdate, isnull(tout.transdate, getdate())) as datediffhour
    from #testm as tin
    left join #testm as tout on tin.item = tout.item and tin.whse = tout.whse and tin.transdate <= tout.transdate and tin.qty = -1*tout.qty
where tin.loc = 'qc' and tout.loc = 'qc'
) as t
where (firstrank = secondrank or t.td2 is null) and t.qty > 0
order by t.transdate
它有两个问题:

它跳过了第5排

secondrank和firstrank只是猜测,因为我不太熟悉稠密等级-我是否正确使用了它?

我使用了行数而不是稠密等级。这里只需要一个。注意,我们有一个t_in.transdate
Select * from 
  (Select test1.*,      
      datediff(hour, test1.transdate, Coalesce(test2.transdate, getdate())) as datediffhour,
      row_number() over (partition by test1.item, test1.loc, test1.transdate order by test1.transdate) as ranking
    from #testm test1
    left join #testm test2 
    on test1.item = test2.item
   and test1.loc = test2.loc 
   and test1.whse = test2.whse
   and test1.qty + test2.qty = 0
   and test1.transdate < test2.transdate
    where test1.qty > 0)c
where ranking=1
使用外部应用程序。大概是这样的:

select t.*, tnext.*
from #testm t outer apply
     (select top (1) tnext.*
      from #testm tnext
      where tnext.loc = t.loc and tnext.item = t.item and
            tnext.transdate > t.transdate
      order by tnext.transdate asc
     ) tnext;

如果您只是加入到top 1,那么交叉应用或外部应用是值得考虑的,因此您可以按照以下方式执行操作:从测试t1中选择t1.item,OA.item外部应用从测试t2中选择top 1*,其中t1.id=t2.id作为OA*@Yuropoor。作为文本表所需的结果将大有帮助。@GordonLinoff添加了一个结果表。
select t.*, tnext.*
from #testm t outer apply
     (select top (1) tnext.*
      from #testm tnext
      where tnext.loc = t.loc and tnext.item = t.item and
            tnext.transdate > t.transdate
      order by tnext.transdate asc
     ) tnext;