2012-08-01 50 views
1

我想查詢返回結果的順序有點內外。我有一張客戶訂單表,我希望檢索N個最早的訂單,但最大限度地增加了正在處理的不同客戶的數量。我將它描述爲「反序」,因爲排序順序是這樣的,即通常彼此相鄰的東西儘可能分散。反序查詢結果

CREATE TABLE custorders (
    order_id integer PRIMARY KEY, 
    customer, 
    data 
); 

INSERT INTO custorders VALUES 
    (1,'joe','xyz'), 
    (2,'joe','abc'), 
    (3,'joe','def'), 
    (4,'sam','qwe'), 
    (5,'sam','rty'); 

我可以爲每一個客戶的東西單最早的順序一樣

SELECT * 
FROM custorders 
WHERE order_id IN 
(
SELECT MIN(order_id) FROM custorders GROUP BY customer 
); 

但我堅持試圖獲得2最早的爲每一個客戶,或(我真正想要的)的所有客戶中的10個最古老的訂單可最大限度地提高不同客戶的數量。也就是說,如果有20個客戶,它會給10個不同的客戶,但是如果只有8個不同的客戶都有多個待定訂單,那麼2個客戶會在結果中出現多次。

我在sqlite 3中工作,所以使用特定於其他數據庫的功能的解決方案沒有幫助。

回答

0

你不行。 SQL不能這樣做。

一般來說,SQL無法跨行比較數據,只能在它們之間進行比較。

您正在嘗試整理行之間的數據(兩個最老的等)。

你可以嘗試像min(order_id) + 2之類的把戲(找到min所有記錄比其他min較大),但它們是不可擴展的。

對不起。

PS。 sqllite可能有一些特殊的功能,但我不熟悉它。我的答案是一般的SQL。

0

嘗試類似這樣的事情。我還沒有測試過它。邏輯是隻選擇2個order_id值較低的記錄,其中MIN()只返回一個值。

SELECT * FROM custorders 
    WHERE order_id IN 
    (
    SELECT order_id FROM custorders GROUP BY customer 
    ORDER BY order_id ASC 
    LIMIT 2 
    ) 
    ; 
+0

是否sqllite有'LIMIT'的選擇嗎? – Ariel 2012-08-01 23:39:51

+0

@Ariel我不確定我的答案是針對一般SQL。 – 2012-08-01 23:49:09

+0

@Ariel是的,我打算回答以前有點類似的查詢,但不能讓sqlfiddle運行這檯筆記本電腦,所以無法測試它。 – Fluffeh 2012-08-02 00:07:44

0

前言:這是未經測試(抱歉,這檯筆記本電腦是不是在玩與sqlfiddle球),但我認爲這可能爲你工作:

select 
    out.customer, 
    group_concat(
     select 
      a.order_id 
     from 
      custOrders a 
     where 
      a.customer=out.customer 
     order by 
      order_id asc 
     limit 2 
    ) as outStanding 
from 
    custOrders out 
limit 10 
0

SQLlite似乎並不支持TOP關鍵詞。在按客戶分組的子查詢中,限制10可能會給您10個客戶,而不是每個客戶的前10個客戶。

實現頂部自己......

我在這裏適應一個MySQL的解決方案,因此與sqllite經驗的人想要清理它,感覺很自由。像下面的東西應該工作。

我們需要映射order_id,以便每個客戶都有連續的值。我們想要分配由我們的客戶自動排序的rowid,然後按升序排列他的order_id,以便我們得到最早的第一個。 rowid是一個隱藏字段,如果我們不使用主鍵,它將被分配給我們。

CREATE TEMP TABLE temp(
    order_id INTEGER, 
    customer text, 
    data text 
) AS SELECT * FROM custorders ORDER BY customer, order_id ASC; 

現在我們的rowid關,以鍵來確定什麼我們的第一個10是爲每一個客戶

SELECT t1.* FROM temp AS t1 JOIN (
    SELECT customer, MIN(rowid) AS min FROM temp GROUP BY customer 
) AS t2 ON t2.min + 10 < t1.rowid AND t2.customer = t1.customer;