Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / SQLite [игнор отключен] [закрыт для гостей] / Помогите с запросом / 11 сообщений из 11, страница 1 из 1
16.12.2009, 20:16
    #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
17.12.2009, 18:55
    #36372442
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
первичный ключ определен?
...
Рейтинг: 0 / 0
17.12.2009, 21:32
    #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
18.12.2009, 20:54
    #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
18.12.2009, 20:59
    #36374887
super_b
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
Все равно вам нужно извлечь _все_ данные, индекс тут не поможет. Фактически, вы пытаетесь алгоритм сжатия реализовать на SQL - если добавить еще кол-во элементов в каждой из последовательных серий, получится простейший архиватор :-)

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

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

Простите, где "гонять" данные?! SQLite - встраиваемая СУБД, исполняется в адресном пространстве приложения, так что "гонять" ничего не нужно. Что касается извлечения _всех_ полей - это неизбежно в любом случае для СУБД с построчным хранением данных, каковых подавляющее большинство (эскулайт, постгрес, мускуль, оракл и проч.).
...
Рейтинг: 0 / 0
19.12.2009, 00:57
    #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
19.12.2009, 01:38
    #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
19.12.2009, 19:53
    #36375661
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Помогите с запросом
MBGWhite Owl...Страшный запрос, даже если создать индекс.С этим никто не спорит :)
Чисто как игра ума, решить задачу не выходя за пределы SQL возможно. Получится конечно кошмар с точки зрения производительности, но решить ее возможно.
Намного правильней будет
либо добавить в таблицу флаг "переключаем на новое значение".

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

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

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


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


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

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

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

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


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