2016-07-14 1 views
1

Я ищу варианты выбора первой записи для каждой группы в SQLite, где сортировка группы осуществляется по составному ключу.SQLite - First Per Group - Composite Order & Opposing Порядок сортировки

Пример таблицы:

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

Я считаю, что это будет работать в 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 
     ); 
+0

Ницца, оба запроса давая 'WHERE (а, Ь) = (SELECT а, Ь ОТ х)', но, будучи SQLite совместимы. Я дам им обойтись, а потом напряг мой мозг, какой вариант наименее запутанный * (за то, что бедный Dev должен иметь с ним дело - это год) *. – MatBailie

+0

@MatBailie. , , Хотя я не в восторге от второго решения, он, вероятно, более ясен тем, кто впервые читает запрос. –

+0

пошел с первым, чтобы избежать проблем с неявными преобразованиями типов. Затем добавлены разумные комментарии относительно корреляции и порядка, аналогично разбиениям и порядку в аналитических функциях. Уделили одно интересное ограничение. Поля внешнего запроса можно ссылаться в предложении WHERE, но не в ORDER BY. Не уверен, что это означает, что это неподдерживаемая функциональность. Будет копать глубже еще один день. – MatBailie