一列多行

时间:2017-03-02 17:52:30

标签: sql sql-server

道歉,我应该添加每一栏并完成问题而不仅仅是部分。

我有一张表A,用于存储从客户收到的所有已发出的发票(ID 1)付款(ID 4)。有时客户分2-3次付款。我想查找发票和为发票收取的最后一笔付款之间的日期差异。我的数据看起来像这样

**a.cltid**|**A.Invnum**|A.Cash|A.Date    | a.type| a.status
70         |112         |-200  |2012-03-01|4      |P
70         |112         |-500  |2012-03-12|4      |P
90         |124         |-550  |2012-01-20|4      |P
70         |112         |700   |2012-02-20|1      |p
55         |101         |50    |2012-01-15|1      |d
90         |124         |550   |2012-01-15|1      |P

我正在运行

Select *, Datediff(dd,T.date,P.date)
from (select a.cltid, a.invnumber,a.cash, min(a.date)date 
      from table.A as A
where a.status<>'d' and a.type=1
group by a.cltid, a.invnumber,a.cash)T
join 
Select *
from (select a.cltid, a.invnumber,a.cash, min(a.date)date 
      from table.A as A
where a.status<>'d' and a.type=4
group by a.cltid, a.invnumber,a.cash)P

on

T.invnumb=P.invnumber and T.cltid=P.cltid

我怎样才能让它发挥作用?所以它告诉我

70|112|-500|2012-03-12|4|P 70|112|700|2012-02-20|1|p|22
90|124|-550|2012-01-20|4|P 90|124|550|2012-01-15|1|P|5

编辑***

4 个答案:

答案 0 :(得分:1)

您可以使用row_number按递减日期的顺序在每个cltid中指定序列号,然后过滤以获取每个cltid的第一行,该行将是该cltid的最新日期行:

select *
from (
    select A.*,
        row_number() over (
            partition by a.cltid order by a.date desc
            ) rn
    from table.A as A
    ) t
where rn = 1;

它将为每个客户返回一行(具有最新日期)。如果要返回具有最新日期的所有行,请改用rank()

答案 1 :(得分:1)

使用排名功能获取所有列:

select a.*
from (select a.*,
             row_number() over (partition by cltid order by date desc) as seqnum
      from a
     ) a
where seqnum = 1;

如果您只想要日期,请使用聚合。您的查询的问题是group by子句包含太多列:

select a.cltid, max(a.date) as date 
from table.A as A
group by a.cltid;

min()返回的第一个日期不是最后一个日期。

答案 2 :(得分:1)

有很多方法可以做到这一点。以下是其中一些:

测试设置:http://rextester.com/VGUY60367

with common_table_expression as ()使用 row_number()

cross

select distinct a.cltid , a.Invnum , x.Cash , x.[date] from a cross apply ( select top 1 cltid, Invnum , [date] , Cash from a as i where i.cltid =a.cltid and i.Invnum=a.Invnum order by i.[date] desc ) as x; apply 版本:

select top 1 with ties
    *
  from a
  order by 
    row_number() over (
      partition by cltid, Invnum
          order by [date] desc
      )

top with ties 版本:

+-------+--------+---------------------+------+
| cltid | Invnum |        date         | Cash |
+-------+--------+---------------------+------+
|    70 |    112 | 12.03.2012 00:00:00 | -500 |
|    90 |    124 | 20.01.2012 00:00:00 | -550 |
+-------+--------+---------------------+------+

所有回报:

RelativeSource

答案 3 :(得分:0)

您可以通过以下方式获得所需的o / p:

Select 
   a.cltid, a.invnumber,a.cash, max(a.date) [date]
from  
   YourTable a
group by 
   a.cltid, a.invnumber, a.cash, a.date