Sqlite:选择,根据一个属性desc进行分组。并根据另一个asc排序

时间:2014-12-24 01:13:47

标签: sql sqlite sorting group-by

根据属性按降序分组的最佳方法是什么,但按升序按其他方式排序。

CREATE TABLE IF NOT EXISTS
logs  (id INTEGER NOT NULL,
       prompt INTEGER NOT NULL,
       value TEXT,
PRIMARY KEY (id));

INSERT INTO logs(id, prompt, value) VALUES(1, 10, "a");
INSERT INTO logs(id, prompt, value) VALUES(2,  4, "a");
INSERT INTO logs(id, prompt, value) VALUES(3, 10, "b");
INSERT INTO logs(id, prompt, value) VALUES(4,  6, "c");
INSERT INTO logs(id, prompt, value) VALUES(5,  5, "c");
INSERT INTO logs(id, prompt, value) VALUES(6,  4, "d");
INSERT INTO logs(id, prompt, value) VALUES(7,  4, "e");
INSERT INTO logs(id, prompt, value) VALUES(8, 10, "a");
INSERT INTO logs(id, prompt, value) VALUES(9, 10, "z");

现在,我想要一个请求:

  1. 根据提示分组(每个不同的提示只有一行)

  2. 仅保留最大 ID

  3. 行的
  4. 按升序 ID 排序(我不需要保留)

  5. 所以我需要

    prompt | value
       10  |  "z"
        4  |  "e"
        6  |  "c"
        5  |  "c"
    

    这怎么可能?它怎么能不太低效?你可以避免中间请求(即从选择中选择 - 我觉得可能会这样做,但不知道如何)。

    更新:我能做到的最好的是进行中间查询并使用MIN运算符:

    SELECT MIN(id), prompt, lvalue
    FROM logs
    INNER JOIN
        (SELECT prompt as lprompt, value as lvalue
         FROM logs
         GROUP BY prompt ORDER BY id DESC)
    ON
      prompt = lprompt
    GROUP BY prompt ORDER BY id ASC;
    

    它有效,但我不禁觉得这是一个糟糕的解决方案。

    更新2 :我想澄清一下,我想要出现提示的第一个 ID,以及 last 值出现;然后按照第一个ID的升序整个排序。

    id  |prompt | value
     1  |   10  |  "z"
     2  |    4  |  "e"
     4  |    6  |  "c"
     5  |    5  |  "c"
    

2 个答案:

答案 0 :(得分:1)

使用不存在的查询来选择ID最大的提示和值

select prompt, value
from logs l1
where not exists (
    select 1 from logs l2
    where l2.prompt = l1.prompt
    and l2.id > l1.id
)
order by l1.id

或使用子查询直接为每个提示选择最大的ID

select prompt, value
from logs l1
where id = (
    select max(id) from logs l2
    where l2.prompt = l1.prompt
)
order by l1.id

选择与最大id绑定的提示值,并按提示的最小id

对结果进行排序
select t1.prompt, t2.value from (
  select prompt, min(id) minid, max(id) maxid
  from logs
  group by prompt
) t1 join logs t2 on t1.maxid = t2.id
order by t1.minid

http://sqlfiddle.com/#!7/cac0b

答案 1 :(得分:1)

你可以尝试:

select minid, lprompt, lvalue from
(SELECT prompt as lprompt, value as lvalue, min(id) as minid, max(id) as maxid
 FROM logs
 GROUP BY prompt ORDER BY id DESC) sq
order by minid

SQLFiddle here.