首页 > 解决方案 > SQL 在两行之间进行选择

问题描述

我有一张这样的桌子:

  C         A         B
-------|----------|-----------|
  16         11111       030000
  16         11111       050000
  16         11111       080000
  16         22222       010000
  16         22222       020000
  16         22222       050000
  16         22222       060000
  16         22222       070000

我需要选择 11111 050000 和 22222 050000 之间的所有内容,包括。

什么 SQL 是正确的?

我拥有的最后一个但它不起作用:

SELECT * 
FROM table 
WHERE A <= 22222 
  AND B < 050000 IN (SELECT id FROM table 
                     WHERE C = 16 AND B >= 050000 
                       AND A BETWEEN 11111 AND 22222

标签: sqlbetween

解决方案


有一些引擎,比如 SQLite,可以让你直接比较行和行:

SELECT * FROM table WHERE (A, B) BETWEEN (11111, '050000') AND (22222, '050000')

但当然,这不是标准的,您可能会发现自己需要在需要您编写标准 SQL 代码的引擎中执行此操作。在这种情况下,问题是,值在这两行之间意味着什么?

在这种情况下,表格先按 A 排序,然后按 B 排序。因此,如果 X 行位于 P 行和 Q 行之间,那么(将 R(C) 表示为 R 行的 C 列)P(A) < X (A) < Q(A) (因为在这种情况下 A 的值严格介于它们之间,并且由于 A 是主排序键,因此该行将始终存在)或 A 的值与端点之一匹配,然后考虑 B 的值。这分为两种情况:P(A) = X(A) 和 P(B) <= X(B),并且 X(A) = Q(A) 和 X(B) <= Q(B)。

还有一种特殊情况:如果 P(A) = Q(A),那么只有 B 重要,但这必须特殊处理,因为分别使用上面的两个条件会匹配多余的行。

因此,让我们将所有这些写入参数化查询,使用四个查询参数:a1, :b1, :a2,:b2来显示所有情况:

SELECT
  *
FROM
  table
WHERE
  CASE WHEN :a1 = :a2 THEN
    B BETWEEN :b1 AND :b2
  ELSE
    (A > :a1 AND A < :a2) OR
    (A = :a1 AND B >= :b1) OR
    (A = :a2 AND B <= :b2)
  END

这就是一般的解决方案。


推荐阅读