根据一定条件将多行合并为一行

时间:2012-12-10 10:02:51

标签: sql sql-server row

我有这样的数据:

STARTDATE ENDDATE AMOUNT INVNO

  • 2012-11-07 09:23:48.000 2012-11-07 09:23:59.000 0.00000000 000000000002012
  • 2012-11-07 09:23:59.000 2012-11-07 10:14:02.000 0.00000000 000000000002012
  • 2012-11-07 10:14:02.000 2012-11-07 10:15:13.000 0.00000000 000000000002012
  • 2012-11-07 10:15:13.000 2012-11-07 10:34:08.000 0.00000000 000000000002012
  • 2012-11-07 10:34:08.000 2012-11-07 11:09:33.000 4000.00000000 000000000002012
  • 2012-11-07 11:09:33.000 2012-11-07 11:10:3​​5.000 4000.00000000 000000000002012

我希望他们合并成一行:

  • 2012-11-07 09:23:48.000 2012-11-07 11:10:3​​5.000 8000.00000000 000000000002012 STARTDATE字段中的第一行开始日期,ENDDATE字段中的最后一行结束日期和AMOUNT字段中金额的SUM。

感谢您的帮助

ps:但如果数据开始日期与前一行的结束日期不同,则必须开始新行。如下所示:

  • 2012-11-07 09:23:48.000 2012-11-07 09:23:59.000 20.00000000 000000000002012
  • 2012-11-07 09:23:59.000 2012-11-07 10:14:02.000 30.00000000 000000000002012
  • 2012-11-07 10:16:09.000 2012-11-07 10:19:13.000 40.00000000 000000000002012
  • 2012-11-07 10:19:13.000 2012-11-07 10:34:08.000 50.00000000 000000000002012

应该是这样的:

  • 2012-11-07 09:23:48.000 2012-11-07 10:14:02.000 50.00000000 000000000002012
  • 2012-11-07 10:16:09.000 2012-11-07 10:34:08.000 90.00000000 000000000002012

2 个答案:

答案 0 :(得分:1)

select min(startdate),max(enddate),sum(amount),INVNO 
       from T 
       group by INVNO

答案 1 :(得分:0)

以下是一些示例数据 - 我已将您的第二个示例的发票号更改为... 13以区分它。

--DROP TABLE #LINES
CREATE TABLE #Lines(
STARTDATE datetime, 
ENDDATE datetime, 
AMOUNT money,
INVNO varchar(50)
)

INSERT INTO #Lines
SELECT 
'2012-11-07 09:23:48.000', '2012-11-07 09:23:59.000', 0.00000000, 000000000002012
UNION ALL SELECT
'2012-11-07 09:23:59.000', '2012-11-07 10:14:02.000', 0.00000000, 000000000002012
UNION ALL SELECT
'2012-11-07 10:14:02.000', '2012-11-07 10:15:13.000', 0.00000000, 000000000002012
UNION ALL SELECT
'2012-11-07 10:15:13.000', '2012-11-07 10:34:08.000', 0.00000000, 000000000002012
UNION ALL SELECT
'2012-11-07 10:34:08.000', '2012-11-07 11:09:33.000', 4000.00000000, 000000000002012
UNION ALL SELECT
'2012-11-07 11:09:33.000', '2012-11-07 11:10:35.000', 4000.00000000, 000000000002012

UNION ALL SELECT
'2012-11-07 09:23:48.000', '2012-11-07 09:23:59.000', 20.00000000, 000000000002013
UNION ALL SELECT
'2012-11-07 09:23:59.000', '2012-11-07 10:14:02.000', 30.00000000, 000000000002013
UNION ALL SELECT
'2012-11-07 10:16:09.000', '2012-11-07 10:19:13.000', 40.00000000, 000000000002013
UNION ALL SELECT
'2012-11-07 10:19:13.000', '2012-11-07 10:34:08.000', 50.00000000, 000000000002013

然后试试这个

;
WITH 
    InvGroupStartDates AS
    (
        select
            InvGroupStartDate = L1.STARTDATE, 
            L1.INVNO, 
            INVGroupNo = ROW_NUMBER() OVER (PARTITION BY L1.INVNO ORDER BY L1.StartDate )
        from #Lines L1
        where not exists(
            select *
            from #Lines L2
            where L1.ENDDATE = L2.STARTDATE
            and L1.INVNO = L2.INVNO
            )
    ),

    InvGroupRanges AS
    (
        select 
            IGSD1.INVNO, 
            IGSD1.InvGroupStartDate, 
            InvGroupEndDateEx = IGSD2.InvGroupStartDate
        from InvGroupStartDates IGSD1
            left join InvGroupStartDates IGSD2
                on IGSD1.INVNO = IGSD2.INVNO
                and IGSD1.INVGroupNo = IGSD2.INVGroupNo - 1
    )
SELECT 
    STARTDATE = InvGroupRanges.InvGroupStartDate,
    INVNO = InvGroupRanges.INVNO,
    ENDDATE = MAX( L.ENDDATE ),
    AMOUNT = SUM( L.Amount )
from #Lines L
    inner join InvGroupRanges
        on L.STARTDATE >= InvGroupRanges.InvGroupStartDate
        and ( InvGroupRanges.InvGroupEndDateEx is NULL OR L.ENDDATE < InvgroupRanges.InvGroupEndDateEx )
group by InvGroupRanges.InvGroupStartDate, InvGroupRanges.INVNO

代码确定发票行范围的开头(相同的发票号,只有那些没有前一行的那些)。然后它得到发票行范围的结束 - 结束日期不包括在内,因为它是后续范围的开始。

最后,它使用这些开始/结束发票行范围日期行来获取您的数据。