从数据库获取不同范围的多个ID的结果

时间:2018-11-14 14:45:14

标签: sql

我在db中有许多用于时间戳记的ID。例如:

    id  timestamp  
    1 '2018-11-14 10:00:00'
    2 '2018-11-14 10:00:00'
    3 '2018-11-14 10:00:00'
    4 '2018-11-14 10:00:00'
    1 '2018-11-14 10:01:00'
    2 '2018-11-14 10:01:00'
    3 '2018-11-14 10:01:00'
    4 '2018-11-14 10:01:00'
    1 '2018-11-14 10:02:00'
    2 '2018-11-14 10:02:00'
    3 '2018-11-14 10:02:00'
    4 '2018-11-14 10:02:00'
    1 '2018-11-14 10:03:00'
    2 '2018-11-14 10:03:00'
    3 '2018-11-14 10:03:00'
    4 '2018-11-14 10:03:00'
    1 '2018-11-14 10:04:00'
    2 '2018-11-14 10:04:00'
    3 '2018-11-14 10:04:00'
    4 '2018-11-14 10:04:00'

我需要编写一个查询,该查询可以选择例如id = 2,3但时间戳的范围仅从'2018-11-14 10:01:00'到'2018-11-14 10:02:00'包括ID 2和ID 3从'2018-11-14 10:02:00'到'2018-11-14 10:04:00' 如果是一条记录,它将是

SELECT id, timestamp 
FROM table 
WHERE id = 2 
  AND '2018-11-14 10:01:00' <= timestamp 
  AND timestamp <= '2018-11-14 10:03:00'

但是类似的多重条件呢?

UPD:手动构建查询不是问题,但是我可以动态获取id和时间戳,因此需要动态构建此查询,而无需事先知道id和时间戳

2 个答案:

答案 0 :(得分:4)

您可以简单地使用逻辑运算符... <span v-text="search.doctor.specialty"></span>的组合:

AND/OR

更简洁的书写方式可以是使用SELECT id, timestamp FROM table WHERE (id = 2 AND timestamp >= '2018-11-14 10:01:00' AND timestamp <= '2018-11-14 10:02:00') OR (id = 3 AND timestamp >= '2018-11-14 10:02:00' AND timestamp <= '2018-11-14 10:04:00')

BETWEEN .. AND ..

编辑(基于您的编辑):为了动态地构建查询,您只需要使用应用程序代码来准备查询字符串(例如:PHP,C ++,Java等) )

答案 1 :(得分:1)

先前的回答非常有用,但是由于我使用的是Spring Data JPA,因此构建动态本机查询与我无关。因此,我找到了另一个解决方案: Spring Specification。在此链接中还描述了Querydsl,但不适用于当前版本的lombok(谁知道它将来会如何工作)。

因此,我选择了规范。它提供了动态构建查询的可能性:

  public class MySpecification<T> {

  public MySpecification(){}

  public Specification<T> hasId(Long id){
    return (root, query, criteriaBuilder) -> (criteriaBuilder.equal(root.get("id"), id));
  }

  public Specification<T> greaterThan(Timestamp someTimestamp ){
    return (root, query, criteriaBuilder) -> criteriaBuilder.greaterThan(root.get("timestamp"), firstDpTimestamp);
  }

  ........


@Repository
public interface MyRepository extends JpaSpecificationExecutor<MyEntity> {

@Override
  public List<MyEntity> getMyEntity(long[] ids, Timestamp[] timestamp) {
        MySpecification<MyEntity> mySpec = new MySpecification<>();
        Specification<MyEntity> spec = where( mySpec.hasId(ids[0]))
            .and(mySpec.greaterThan(timestamp[0]);
    for (int i = 1; i < ids.length; i++) {
      spec = spec.or(mySpec.hasId(ids[i]).and(mySpec.greaterThan(timestamp[i]));
    }
    return repo.findAll(spec);
  }