powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Помогите с запросом
11 сообщений из 11, страница 1 из 1
Помогите с запросом
    #36370343
super_b
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть таблица с полем State, нужно выбрать уникальные из подряд идущих значений этого поля. Например, есть записи (значение поля State): 1 1 2 3 3 3 4 4 1 5 5 2 2 => нужно выбрать записи с по значением поля: 1 2 3 4 1 5 2

Смысл задачи: выбирать только переходы состояний.

Выбирать нужно только первое (не любое, и не последнее) из подряд идущих дублей, остальные пропускать.

Помогите написать максимально простой (стандартный) запрос, по идее задача достаточно распространенная.
...
Рейтинг: 0 / 0
Помогите с запросом
    #36372442
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
первичный ключ определен?
...
Рейтинг: 0 / 0
Помогите с запросом
    #36372621
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
Задачка на потоковую обработку, т.е. уровня приложения. Как вариант:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
$ sqlite3 /tmp/test.db "select * from state"
 1 
 1 
 2 
 3 
 3 
 3 
 4 
 4 
 1 
 5 
 5 
 2 
 2 
$ sqlite3 /tmp/test.db "select * from state"|uniq
 1 
 2 
 3 
 4 
 1 
 5 
 2 

Все равно вам нужно извлечь _все_ данные, индекс тут не поможет. Фактически, вы пытаетесь алгоритм сжатия реализовать на SQL - если добавить еще кол-во элементов в каждой из последовательных серий, получится простейший архиватор :-)
...
Рейтинг: 0 / 0
Помогите с запросом
    #36374883
super_b
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owlпервичный ключ определен?
да, id. порядок следования по нему (order by id) - т.е. по мере добавления состояний.

был бы pl/sql можно было бы заюзать lag/lead,
на C# делается еще проще - простой последовательной обработкой:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
            using (var enumerator = source.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                    yield break;
                T prev = enumerator.Current;
                yield return prev;
                while (enumerator.MoveNext())
                {
                    T current = enumerator.Current;
                    if (!pred(current, prev))
                        yield return current;
                    prev = current;
                }
            }

но тут SQL. неужели это такой редкий запрос?
...
Рейтинг: 0 / 0
Помогите с запросом
    #36374887
super_b
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Все равно вам нужно извлечь _все_ данные, индекс тут не поможет. Фактически, вы пытаетесь алгоритм сжатия реализовать на SQL - если добавить еще кол-во элементов в каждой из последовательных серий, получится простейший архиватор :-)

так то оно так, с двумя _НО_:одно дело БД пролопатит таблицу на такие соответствия - по идее шустрее тк не будет извлекать _все_ поля, + не будет гонять данные между слоем БД и business-tier
...
Рейтинг: 0 / 0
Помогите с запросом
    #36374943
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
super_bВсе равно вам нужно извлечь _все_ данные, индекс тут не поможет. Фактически, вы пытаетесь алгоритм сжатия реализовать на SQL - если добавить еще кол-во элементов в каждой из последовательных серий, получится простейший архиватор :-)

так то оно так, с двумя _НО_:одно дело БД пролопатит таблицу на такие соответствия - по идее шустрее тк не будет извлекать _все_ поля, + не будет гонять данные между слоем БД и business-tier

Простите, где "гонять" данные?! SQLite - встраиваемая СУБД, исполняется в адресном пространстве приложения, так что "гонять" ничего не нужно. Что касается извлечения _всех_ полей - это неизбежно в любом случае для СУБД с построчным хранением данных, каковых подавляющее большинство (эскулайт, постгрес, мускуль, оракл и проч.).
...
Рейтинг: 0 / 0
Помогите с запросом
    #36375046
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
super_bWhite Owlпервичный ключ определен?
да, id. порядок следования по нему (order by id) - т.е. по мере добавления состояний.
В следующий раз сразу публикуй скрипт создающий тестовую таблицу. Я сегодня добрый, поэтому написал ее за тебя.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
create table t(id int, value int);

insert into t values( 1 , 1 );
insert into t values( 2 ,  1 );
insert into t values( 3 ,  2 );
insert into t values( 4 ,  3 );
insert into t values( 5 ,  3 );
insert into t values( 6 ,  3 );
insert into t values( 7 ,  4 );
insert into t values( 8 ,  4 );
insert into t values( 9 ,  1 );
insert into t values( 10 ,  5 );
insert into t values( 11 ,  5 );
insert into t values( 12 ,  2 );
insert into t values( 13 ,  2 );

select * from t;


select t1.id, t1.value
from t as t1
where t1.value != coalesce(
                           (select t2.value from t as t2 where t1.id>t2.id order by t2.id desc limit  1  )
                           ,  0 )
order by id;
...
Рейтинг: 0 / 0
Помогите с запросом
    #36375054
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White Owl...

Страшный запрос, даже если создать индекс. Вообще это частный случай более общей проблемы, я уже написал функцию, которая это решает, да еще предоставляет эмуляцию конструкции "distinct on":
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
 select value from t where distincton( 0 ,value)= 1 ;
 1 
 2 
 3 
 4 
 1 
 5 
 2 
Первый аргумент должен быть любым числом, а если сразу указать value, то работать не будет, ибо интерфейс не документированный и весьма хитрый:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
static void distinctonFunc(
  sqlite3_context *pCtx,   /* Function context */
  int nArg,                /* Number of function arguments */
  sqlite3_value **argv     /* Values for all function arguments */
){
  int i;
  unsigned int *pHash;
  unsigned int hash;
  struct MurmurHash2A ctx;

  MurmurHash2A_Begin(&ctx);
  for(i= 0 ; i < nArg; i++){
    const char *zData = (char*)sqlite3_value_blob(argv[i]);
    if( zData ){
        MurmurHash2A_Add(&ctx,(unsigned char*)zData, sqlite3_value_bytes(argv[i]));
    }
  }
  hash = MurmurHash2A_End(&ctx);

  pHash = (unsigned int*)sqlite3_get_auxdata(pCtx,  0 );
  if( pHash== 0  ){
    pHash = sqlite3_malloc( sizeof(*pHash) );
    if( pHash== 0  ){
      sqlite3_result_error_nomem(pCtx);
      return;
    }
    *pHash = hash;
    sqlite3_set_auxdata(pCtx,  0 , pHash, sqlite3_free);
    sqlite3_result_int(pCtx,  1 );
  }else{
    sqlite3_result_int(pCtx, *pHash==hash? 0 : 1 );
    *pHash = hash;
  }
}

Вместо использования хэша можно хранить бинарную строку со всеми значениями, но я полагаю, что вероятность коллизии 1 к 4 миллиардам не так существенна, а при использовании нескольких аргументов distincton(0,value1,value2,...,valueN) имеет смысл именно хэш.

У меня в продакшене есть несколько запросов, которые требуют подобной оптимизации, т.к. сейчас с помощью триггеров обновляются флаги is_first/is_last у записей, а мне это категорически не нравится. Функция скоро будет опубликована в моем репозитории, см. http://sqlite.mobigroup.ru/
...
Рейтинг: 0 / 0
Помогите с запросом
    #36375661
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MBGWhite Owl...Страшный запрос, даже если создать индекс.С этим никто не спорит :)
Чисто как игра ума, решить задачу не выходя за пределы SQL возможно. Получится конечно кошмар с точки зрения производительности, но решить ее возможно.
Намного правильней будет
либо добавить в таблицу флаг "переключаем на новое значение".

либо считать на клиенте.

А твой любимый подход с написанием расширения для sqlite...
Я соглашусь что это самое производительное и самое нетребовательное к ресурсам решение, но в тоже время это и самое сложное для сопровождения и расширения. Но производительное.... но сложное в сопровождении.... но производительное... но сложное....
...
Рейтинг: 0 / 0
Помогите с запросом
    #36376081
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
White OwlMBGWhite Owl...Страшный запрос, даже если создать индекс.С этим никто не спорит :)
Чисто как игра ума, решить задачу не выходя за пределы SQL возможно. Получится конечно кошмар с точки зрения производительности, но решить ее возможно.
Намного правильней будет
либо добавить в таблицу флаг "переключаем на новое значение".

либо считать на клиенте.


Зачастую бывает лучше два десятка строк для дополнительной функции написать, чем поддерживать в проекте сотни строк кода разработчиков, реализующих эту функциональность триггерами в БД и/или функциями на уровне приложения.


White Owl
А твой любимый подход с написанием расширения для sqlite...
Я соглашусь что это самое производительное и самое нетребовательное к ресурсам решение, но в тоже время это и самое сложное для сопровождения и расширения. Но производительное.... но сложное в сопровождении.... но производительное... но сложное....

Апстрим эскулайта в таких случаях отвечает, что если вам нужно решить вашу задачу - решайте ее, пишите свой код, не стесняйтесь модифицировать исходник, ведь эскулайт - встраиваемая СУБД, так что каждый проект, по идее, пользуется своей собственной сборкой. SQLite API настолько стабилен, что сопровождение сложности не представляет - достаточно раз в месяц сливать свою версию с очередным релизом апстрима.
...
Рейтинг: 0 / 0
Помогите с запросом
    #36376624
MBG
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
MBG
Гость
Переписал для работы без дополнительного модуля murmurhash и сделал поддержку произвольного кол-ва аргументов:

http://sqlite.mobigroup.ru/src/info/c702c868dc

Для работы функции нужен однострочный патч
http://sqlite.mobigroup.ru/src/info/325d887bb1
С этим патчем связаны интересные размышления, пока скажу лишь, что Anton Kovalenko решил написать дополнительный интерфейс, а не патчить существующий. Его патч я в альтернативную ветку включу, а потом посмотрим, удастся ли одному из нас убедить апстрим.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Помогите с запросом
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]