2012-08-01 66 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;