SQL查询没有按预期给出结果

时间:2018-04-19 02:21:22

标签: sql postgresql group-by amazon-redshift partition-by

我需要一些帮助。我有下表(示例如下):

public async virtual Task Test_GetBooksById() {
    //Arrange
    var id = "123";
    Expression<Func<Book, bool>> predicate = t => t.ID == id;
    var dataSource = new List<Book> {
        new Book { ID = id, Description = "HarryPotter"},
        new Book { ID = "124", Description = "HarryPotter2"} 
    }.AsQueryable();

    var expected = dataSource.Where(predicate);

    var response = new FeedResponse<Book>(expected);

    var mockDocumentQuery = new Mock<IFakeDocumentQuery<Book>>();

    mockDocumentQuery
        .SetupSequence(_ => _.HasMoreResults)
        .Returns(true)
        .Returns(false);

    mockDocumentQuery
        .Setup(_ => _.ExecuteNextAsync<Book>(It.IsAny<CancellationToken>()))
        .ReturnsAsync(response);

    var provider = new Mock<IQueryProvider>();
    provider
        .Setup(_ => _.CreateQuery<Book>(It.IsAny<System.Linq.Expressions.Expression>()))
        .Returns((Expression expression) => {                
            if (expression != null) {
                dataSource = dataSource.Provider.CreateQuery<Book>(expression);
            }
            mockDocumentQuery.Object;
        });

    mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Provider).Returns(provider.Object);
    mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.Expression).Returns(() => dataSource.Expression);
    mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.ElementType).Returns(() => dataSource.ElementType);
    mockDocumentQuery.As<IQueryable<Book>>().Setup(x => x.GetEnumerator()).Returns(() => dataSource.GetEnumerator());

    var client = new Mock<IDocumentClient>();

    client.Setup(_ => _.CreateDocumentQuery<Book>(It.IsAny<Uri>(), It.IsAny<FeedOptions>()))
          .Returns(mockDocumentQuery.Object);

    var documentsRepository = new DocumentDBRepository<Book>(client.Object, "123", "123");

    //Act
    var entities = await documentsRepository.GetEntities(predicate);

    //Assert
    entities.Should()
        .NotBeNullOrEmpty()
        .And.BeEquivalentTo(expected);
}

我试图获得如下输出:

EmpID     | Type | timestamp           | block_id
----------------------------------------------------
    1     |  'R' | 2018-04-15 01:13:15 | AB12D
    1     |  'P' | 2018-04-15 05:13:15
    1     |  'P' | 2018-04-15 05:13:15
    1     |  'P' | 2018-04-15 05:13:15
    1     |  'D' | 2018-04-15 07:13:15
    1     |  'D' | 2018-04-15 08:13:15
    1     |  'D' | 2018-04-15 10:13:15
    1     |  'R' | 2018-04-15 13:13:00 | 1X1#1
    1     |  'P' | 2018-04-15 13:15:15
    1     |  'P' | 2018-04-15 13:15:15
    1     |  'P' | 2018-04-15 13:15:15
    1     |  'D' | 2018-04-15 14:13:00
    1     |  'D' | 2018-04-15 15:13:00
    1     |  'D' | 2018-04-15 16:13:37
    2     |  'R' | 2018-04-15 04:15:00 | __08XA
    2     |  'P' | 2018-04-15 04:20:00
    2     |  'D' | 2018-04-15 05:11:33

即,这些是一些块,每个empId可以有多个块。因此,从上面的示例表中,empID&#39; 1&#39;有2个块(从第1行到第7行),第2个从第8行到第14行; empID 2有1个块,第14行到第16行。

EmpID | begin_timestamp | end_timestamp | block_id | P_count | D_count --------------------------------------------------------------------------------- 1 | 2018-04-15 01:13:15 |2018-04-15 10:13:15 | AB12D | 3 | 3 1 | 2018-04-15 13:13:00 | 2018-04-15 16:13:37| 1X1#1 | 3 | 3 2 | 2018-04-15 04:15:00 | 2018-04-15 05:11:33| __08XA | 1 | 1 是一个字母数字字段,可以包含任何随机值。此表也未按上图所示进行排序,仅用于说明目的。我目前处于红移并且有以下查询:

block_id

但这不起作用,因为它没有给出准确的结果。请帮忙!!

1 个答案:

答案 0 :(得分:0)

你真正想要的是lag(ignore nulls),但Postgres不支持。

相反,您可以使用非NULL值的时间戳并使用它来定义组。

select date_trunc('day', timestamp) as date, execution_id,
       min(timestamp) as begin_timestamp, max(timestamp) as end_timestamp,
       max(block_id) as block_id,
       sum(case when Type = 'P' then 1 else 0 end) as P_count,
       sum(case when Type = 'D' then 1 else 0 end) as D_count
from (select t.*,
             max(case when block_id is not null then timestamp end) over 
                 (partition by EmpId
                  order by timestamp
                  rows between unbounded preceding and current row
                 ) as grp
      from myTable t
     ) t
group by empId, grp, date_trunc('day', timestamp)