SQLite - First Per Group - Composite Order&反对排序顺序

时间:2016-07-14 13:02:44

标签: sql sqlite greatest-n-per-group

我正在寻找有关如何在SQLite中选择每组第一条记录的选项,其中组的排序是通过复合键进行的。

示例表:

 Key_1 | Sort1 | Sort2 | Val_1 | Val_2
-------+-------+-------+-------+------- 
   1   |   1   |   3   |   0   |   2
   1   |   1   |   2   |   2   |   4
   1   |   1   |   1   |   4   |   6
   1   |   2   |   2   |   6   |   8
   1   |   2   |   1   |   8   |   1
   2   |   1   |   2   |   0   |   5
   2   |   1   |   1   |   1   |   6
   2   |   2   |   3   |   2   |   7
   2   |   2   |   2   |   3   |   8
   2   |   2   |   1   |   4   |   9

目标:
- 按Key_1 ASC, Sort1 ASC, Sort2 DESC选择数据 - 选择每个唯一Key_1

的第一条记录
 Key_1 | Sort1 | Sort2 | Val_1 | Val_2
-------+-------+-------+-------+------- 
   1   |   1   |   3   |   0   |   2
   2   |   1   |   2   |   0   |   5

分析功能解决方案......

 SELECT
    *
 FROM
 (
    SELECT
        *,
        ROW_NUMBER() OVER (PARTITION BY Key_1
                               ORDER BY Sort1,
                                        Sort2 DESC
                          )
                              AS group_ordinal
    FROM
        table
 )
     sorted
 WHERE
     group_ordinal = 1

费力的ANSI-92方法......

SELECT
    table.*
FROM
    table
INNER JOIN
(
    SELECT
        table.Key1, table.Sort1, MAX(table.Sort2) AS Sort2
    FROM
        table
    INNER JOIN
    (
        SELECT
            Key_1, MIN(Sort1)
        FROM
            table
        GROUP BY
            Key_1
    )
        first_Sort1
            ON  table.Key_1 = first_Sort1.Key_1
            AND table.Sort1 = first_Sort1.Sort1
    GROUP BY
        table.Key1, table.Sort1
)
    first_Sort1_last_Sort2
        ON  table.Key_1 = first_Sort1_last_Sort2.Key_1
        AND table.Sort1 = first_Sort1_last_Sort2.Sort1
        AND table.Sort2 = first_Sort1_last_Sort2.Sort2

这涉及很多嵌套和自连接。当它只包含两个列时,这很麻烦。

我的实际示例有六个排序列。

我也想避免以下内容,因为 (据我所知)保证/确定性......

SELECT
    table.*
FROM
    table
GROUP BY
    table.Key_1
ORDER BY
    MIN(table.Sort1),
    MAX(table.Sort2)

我还有其他选择吗?

1 个答案:

答案 0 :(得分:1)

我相信这可以在SQLite中使用:

select t.*
from table t
where exists (select 1
              from (select t2.*
                    from table t2
                    where t2.id = t.id
                    order by t2.sort1 asc, t2.sort2 desc
                    limit 1
                   ) t2
              where t2.sort1 = t.sort1 and t2.sort2 = t.sort2
             );

我担心SQLite是否允许嵌套子查询中的相关引用。如果没有,您可以使用=并将值连接在一起:

select t.*
from table t
where (sort1 || ':' || sort2) =
          (select (sort1 || ':' || sort2)
           from table t2
           where t2.id = t.id
           order by sort1 asc, sort2 desc
           limit 1
          );