单个查询中的多个分组信息

时间:2015-02-21 06:41:12

标签: sql-server azure

我有一组预定交易(预定日期和预定金额)的结果集,加入了实际交易(实际日期和实际金额)的列表。

我在起诉SQL Azure。

我需要得到的是,对于每个schedule_id,我需要知道:

付款的最后日期(因此,MAX实际日期)。

该付款的相应金额(因此,上述日期的实际金额)

上次付款的ID(Actual_transaction_id)。

s计划的下一个付款日期(因此,MIN scheduled_date,其中ACTUAL日期为空)

上一笔付款金额。

以下是创建测试数据的代码:

    SET DATEFORMAT DMY

DECLARE @tbl TABLE
(
    schedule_id INT NOT NULL,
    scheduled_date DATE NOT NULL,
    actual_date DATE NULL,
    scheduled_amount DECIMAL(16,2) NOT NULL,
    actual_amount DECIMAL(18,2) NULL,
    actual_tranaction_id INT NULL
)

INSERT INTO @tbl
SELECT 77, '2014-06-17', '2014-06-17',292.18, 292.18 ,1 UNION
SELECT 77, '2014-07-17', '2014-07-17',292.18, 292.18 ,2 UNION
SELECT 77, '2014-08-17', '2014-08-17',292.18, 292.18 ,3 UNION
SELECT 77, '2014-09-17', '2014-09-17',292.18, 292.18 ,4 UNION
SELECT 77, '2014-10-17', '2014-10-17',292.18, 292.18 ,5 UNION
SELECT 77, '2014-11-17', '2014-11-17',292.18, 292.18 ,6 UNION
SELECT 77, '2015-02-17', '2015-02-18',504.00, 504.00 ,7 UNION
SELECT 77, '2015-03-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-04-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-05-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-06-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-07-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-08-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-09-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-10-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-11-17', NULL,504.00, NULL, NULL UNION
SELECT 77, '2015-12-17', NULL,504.00, NULL, NULL UNION
SELECT 92, '2014-06-17', '2014-06-17',700.00, 700.00,10 UNION
SELECT 92, '2014-07-17', '2014-07-17',550.00, 700.00, 11 UNION
SELECT 92, '2014-08-17', '2014-08-17',700.00, 700.00, 12 UNION
SELECT 92, '2014-09-17', '2014-09-17',700.00, 700.00, 13 UNION
SELECT 92, '2014-10-17', '2014-10-16',620.00, 580.00, 14 UNION
SELECT 92, '2014-11-17', '2014-11-14',600.00, 601.00, 15 UNION
SELECT 92, '2014-12-17', '2014-12-17',700.00, 702.00, 16 UNION
SELECT 92, '2015-01-17', '2015-01-17',850.00, 851.00, 17 UNION
SELECT 92, '2015-02-17', '2015-02-17',850.00, 853.00, 18 UNION
SELECT 92, '2015-03-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-04-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-05-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-06-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-07-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-08-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-09-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-10-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-11-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2015-12-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2016-01-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2016-02-17', NULL,850.00, NULL, NULL UNION
SELECT 92, '2016-03-17', NULL,850.00, NULL, NULL

SELECT * FROM @tbl

在这种情况下,预期的结果是两行:

scheduleId, lastPaymentDate, lastPaymentAmount, nextPaymentDate, nextPaymentAmount 
77, 2015-02-18, 504.00, 2015-03-17, 504.00 
92, 2015-02-17, 853.00, 2015-03-17, 850.00

这是否可行,以某种方式在一个有效的单个查询中执行此操作?或者它是否需要分解为具有自己的WHERE和分组的多个查询?

2 个答案:

答案 0 :(得分:1)

这是一种方法:

SELECT
  t.schedule_id,
  a.actual_date,
  a.actual_amount,
  s.scheduled_date,
  s.scheduled_amount
FROM (
    select 
      distinct schedule_id
    from 
      tbl
  ) t
  outer apply (
    select top 1
      actual_date,
      actual_amount
    from
      tbl a
    where
      a.schedule_id = t.schedule_id and
      a.actual_date is not null
    order by
      actual_date desc) a
  outer apply (
    select top 1
      scheduled_date,
      scheduled_amount
    from
      tbl s
    where
      s.schedule_id = t.schedule_id and
      s.scheduled_date > getdate()
    order by
      scheduled_date asc) s

派生表提取ID,2外部适用于获取前1的实际和预定金额。

答案 1 :(得分:1)

试试这句话:

;WITH    cte
          AS ( SELECT   * ,
                        ROW_NUMBER() OVER ( PARTITION BY schedule_id ORDER BY actual_date DESC, scheduled_date DESC ) AS rn1 ,
                        ROW_NUMBER() OVER ( PARTITION BY schedule_id ORDER BY actual_date , scheduled_date ) AS rn2
               FROM     @tbl
             )
    SELECT  c1.schedule_id ,
            c2.actual_date ,
            c2.actual_amount ,
            c1.scheduled_date ,
            c1.scheduled_amount
    FROM    cte c1
            JOIN cte c2 ON c1.rn1 = c2.rn2
    WHERE   ( c1.rn1 = 1
              OR c1.rn2 = 1
            )
            AND c2.rn1 = 1

输出:

schedule_id   actual_date     actual_amount   scheduled_date    scheduled_amount
77            2015-02-18      504.00          2015-03-17        504.00
92            2015-02-17      853.00          2015-03-17        850.00