【问题标题】:SQL syntax term for 'WHERE (col1, col2) < (val1, val2)''WHERE (col1, col2) < (val1, val2)' 的 SQL 语法术语
【发布时间】:2016-01-04 01:48:33
【问题描述】:

正如我的问题所述,我想知道在WHERE 子句中我们所说的具有该类型条件的查询类型,即:

SELECT * FROM mytable
WHERE (col1, col2) < (1, 2);

换句话说:
给我所有 col1 小于 '1' 或如果它等于 '1' 则 col2 必须小于 '2' 的记录 - 并且没有任何值是 NULL。

我真的很喜欢这种类型的语法,但不知道关于如何引用这种类型的条件的命名约定是什么。它看起来像一个有条件的元组,但这个名字并没有从我的搜索中给我任何东西。

我的问题源于需要知道这种语法的名称,以便研究如何使用 Criteria API 与 Hibernate、JPA2 和 Postgres 来编写它。

编辑

我能够使用 Criteria API 使用 CriteriaBuilder's function() 调用编写此代码:

//Our left expression (date, id)
Expression leftVal = criteriaBuilder.function("ROW", Tuple.class,     
        from.get("date").as(java.util.Date.class),
        from.get("id").as(Long.class));

//Our right expression ex: ('2015-09-15', 32450)
ParameterExpression<Date> dateParam = criteriaBuilder.parameter(Date.class);
ParameterExpression<Long> idParam = criteriaBuilder.parameter(Long.class);
Expression rightVal = criteriaBuilder.function("ROW", Tuple.class, dateParam, idParam)

//build the first predicate using ROW expressions
Predicate predicate = criteriaBuilder.greaterThan(leftVal, rightVal);

//more query building happens
... 

//construct final query and add parameters to our param expressions
TypedQuery<MyEntity> typedQuery = em.createQuery(criteriaQuery);
typedQuery.setParameter(dateParam, current.getDate());
typedQuery.setParameter(idParam, current.getId());

current 在这种情况下是我检索的记录,作为我们想要在之前或之后获取记录的行。在此示例中,我按照greaterThan 函数调用的说明进行操作。

【问题讨论】:

标签: sql hibernate postgresql pagination criteria


【解决方案1】:

常见的短期只是“行值”。或者您演示的操作的“行值比较”。自 SQL-92 (!) 以来,该功能一直在 SQL 标准中。 Postgres 是目前唯一在所有方面都支持它的主要 RDBMS - 尤其是还具有最佳索引支持。

特别是,表达式 (col1, col2) &lt; (1, 2) 只是 Postgres 中 ROW(col1, col2) &lt; ROW(1, 2) 的简写。 表达式ROW(col1, col2) 也称为row constructor - 就像ARRAY[col1, col2]array constructor

它是更冗长的等效表达式的简写:

col1 < 1 OR (col1 = 1 AND col2 < 2)

... Postgres 可以为此使用(col1, col2)(col1 DESC, col2 DESC) 上的索引。

与 (!) 明显不同

col1 < 1 AND  AND col2 < 2

考虑示例:(1,1) ...

这是 Markus Winand 的演示文稿,详细讨论了分页功能:

"Pagination done the PostgreSQL way" on use-the-index-luke.com.

行值比较从第 20 页开始。我提到的支持矩阵在第 45 页。

我绝不隶属于我引用的任何来源。

【讨论】:

  • 很好的发现,这个分页示例/幻灯片正是我想要的方式(使用行值进行高效查询,索引日期和 id)
【解决方案2】:
WHERE (col1, col2) < (val1, val2)

上述语法称为行值构造函数/元组语法/行子查询

来自doc

ANSI SQL 行值构造语法,有时也称为 AS tuple 语法,即使底层数据库可能不支持 概念。在这里,我们一般指的是多值比较, 通常与组件相关联

也可以称为Row Subqueries

【讨论】:

  • @Patrick 对于更广阔的视野。在纯 ANSI 标准中,它被称为 RVC。
【解决方案3】:

Expression Lists

在比较谓词中使用行值构造函数 (RVC) - 相当长期

RVC 通常出现在 INSERT 语句中,但很少作为 WHERE 子句的一部分。

我怀疑这种语法在 JPA 或 Hibernate Criteria API 中是否有直接支持,但总有一种解决方法可以实现相同的逻辑。

【讨论】:

  • 好吧,这没什么错。无论如何,PostGreSQL 和 Oracle 使用相同的术语。 postgresql.org/docs/9.4/static/functions-comparisons.html RVC 包含在 ANSI 中
  • 确实有一种解决方法可以获得相同的逻辑( (col1 > val1) OR (col1 = val1 AND col2 > val2)),但这实际上比使用行值构造函数的性能更差
  • 显然,它仍在为 JPA 工作:java.net/jira/browse/JPA_SPEC-90
  • @Ish 查看上面的编辑我能够进行 ROW 查询:)
猜你喜欢
  • 2015-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-17
  • 2019-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多