【问题标题】:SQLite - First Per Group - Composite Order & Opposing Sort OrderSQLite - 每个组的第一个 - 复合顺序和相反的排序顺序
【发布时间】:2016-11-17 10:01:58
【问题描述】:

我正在寻找有关如何在 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)

还有其他我没有看到的选项吗?

【问题讨论】:

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


    【解决方案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
              );
    

    【讨论】:

    • 很好,两个查询都提供WHERE (a,b) = (SELECT a,b FROM x),但与 SQLite 兼容。我会让他们两个都试一试,然后让我的大脑思考哪个选项最不容易混淆(因为可怜的开发人员必须处理它是一年的时间)
    • @MatBailie 。 . .虽然我对第二种解决方案并不满意,但对于第一次阅读查询的人来说可能更清楚。
    • 使用第一个以避免隐式类型转换的问题。然后通过类似于分析函数中的分区和排序来添加关于相关性和排序的明智的 cmets。确实资助了一个有趣的限制。外部查询的字段可以在 WHERE 子句中引用,但不能在 ORDER BY 中引用。不确定这是否意味着这是不受支持的功能。改天再深入挖掘。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多