SQL在一个查询中的键之前至少获得n个元素

时间:2017-01-18 13:56:46

标签: sql orientdb

现在我有2个查询:

SELECT * FROM ( 
    SELECT login, permissions FROM User 
    WHERE login < ? 
    ORDER BY DESC login 
    LIMIT ? 
) ORDER BY login

第二个:

SELECT login, permissions FROM User 
WHERE login >= ? 
ORDER BY login 
LIMIT ?

我希望在键之前获得n个结果。

  • 首先,我使用限制n执行第一个查询。
  • 然后我看到收到了多少结果results.count()
  • 如果需要,我会使用剩余的密钥let remaining = n - result.count()执行第二次查询(remaining > 0)。

可以在一个查询中执行此操作吗?

示例:

1. a
2. b
3. c
4. d

get(key = 'a', limit = 2) would return a, b
get(key = 'c', limit = 2) would return a, b
get(key = 'd', limit = 2) would return b, c
get(key = 'd', limit = 3) would return a, b, c

2 个答案:

答案 0 :(得分:2)

如果您需要分页,则提出错误的问题。

即使不熟悉orient db,也可以解答当前的问题。

您需要UNION两个查询:

select * 
from table 
where login < ? 
order by login DESC
limit n

UNION ALL

select * 
from table 
where login >= ? 
order by login 
limit n             -- worst case scenerio all n logins are equal or beyound ?

然后选择该子查询。

SELECT *
FROM ( ... ) as union_query
ORDER BY login
limit n

答案 1 :(得分:1)

您正在寻找的是对您的记录进行排名:您更喜欢密钥前的记录。所以关键的记录被认为是第二好的。然后,您只希望一定量的行尽可能靠近键。可能的排名是根据键的行号,但是在给定的键之前将键乘以-1。例如。在寻找关键d

key  rn
a    -1
b    -2
c    -3
d    +4
e    +5

按等级排序:

key  rn
c    -3
b    -2
a    -1
d    +4
e    +5

所以你首先获得c,然后是b,然后是a,然后是d,然后是e。

我不了解OrientDB,所以这里是标准的SQL:

select login, permissions
from
(
  select 
    login, 
    permissions, 
    case when login < :value then
      -row_number() over (order by login)
    else
      row_number() over (order by login)
    end as rn
  from user
)
order by rn
fetch first :n rows only;