2017-01-18 65 views
0

現在我有2個疑問:SQL拿到鑰匙之前至少n個元素在一個查詢

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()
  • 然後,如果需要(remaining > 0),我使用其餘密鑰let remaining = n - result.count()執行第二個查詢。

可以在一個查詢中做到這一點?

例子:

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 
+0

第一查詢可是沒有選擇任何字段或你錯過了''? –

+0

@JuanCarlosOropeza固定 - >是的,我錯過了,但在Orientdb這是有效的查詢,所以這就是爲什麼我忘了它。這也解釋了權限 - >在關係數據庫中將被視爲未規範化。 –

+0

你知道'n'嗎?或者由'result.count'計算? –

回答

2

如果需要分頁你是問錯了問題。

即使在不熟悉orient db的情況下,也可以查看當前的問題。

您需要UNION都querys:

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 
+0

這正是我的第一個查詢,如果在鍵之前有足夠的記錄,它就會工作,並且它完全不符合我的用例。如果在密鑰前面有3條記錄,並且我想要接收5條記錄,那麼我會將這2條記錄記錄在密鑰後面。 –

+0

我沒有看到你的問題。這就是爲什麼一個好例子需要它。 –

+0

檢查我的編輯。我把它分開,因爲不知道如何將東方sintaxis。但是,首先測試聯合,然後對該子查詢執行選擇。 –

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,那麼,則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; 
+0

這可能是有效的,但是這要求對錶格進行全面掃描,所以如果表格非常大,效率不是很高。你還需要在最後登錄命令,OP需要一個pagging函數,所以'a'應該是第一個,而不是'c' –

相關問題