Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT по первой части числа / 12 сообщений из 12, страница 1 из 1
19.10.2015, 11:55
    #39079905
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
Добрый день.

Есть числа:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
465678685446733
465678685443564
134356575777868
465678355564356
134356574357868
465678685345454
454367867854777
233535436546667
...



Надо выбрать все строки у которых первые цифры уникальны. Например первые 6 это будет:

Код: sql
1.
2.
3.
4.
465678|685446733
134356|575777868
454367|867854777
233535|436546667



Как сделать такой запрос и чтобы он стоил как можно меньше?

У меня есть несколько идей:

1. Хранить все в строках, тогда через LIKE, но не знаю будет ли работать такая конструкция с DISTINCT. И тут еще вопрос про индексацию.. Такие числовые значения прекрасно идексируются, а строки врятли будут также хороши индексироваться, хотя я не привязан к числам, мне главное чтобы каждый символ в этом большим числе был одним из четырех, сейчас это 1,2,3 или 4.

2. Делать предварительное разделение столбца (при запросе) и дальше по разделенной части делать DISTINCT. Тут я не знаю как делать такое разделение...
...
Рейтинг: 0 / 0
19.10.2015, 12:00
    #39079922
p2.
p2.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
ClosiusНадо выбрать все строки у которых первые цифры уникальны .противоречие. все или только уникальные?

ClosiusКак сделать такой запрос и чтобы он стоил как можно меньше?Сделать несколько запросов и выбрать с минимальной стоимостью.

ClosiusИ тут еще вопрос про индексациюиндексация перебору всех записей не помощник.
...
Рейтинг: 0 / 0
19.10.2015, 12:06
    #39079931
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
UPD ко второму пункту: Не знаю как сделать это с меньшей стоимостью.. Просто делить все поля (WHERE a / 100000 и отбрасывать дробную часть) мне кажется достаточно затратно... Может есть способ лучше, по маске какой нибудь...
...
Рейтинг: 0 / 0
19.10.2015, 12:08
    #39079934
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
p2.ClosiusНадо выбрать все строки у которых первые цифры уникальны .противоречие. все или только уникальные?


Уникальные
...
Рейтинг: 0 / 0
19.10.2015, 12:09
    #39079938
Щукина Анна
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
ClosiusUPD ко второму пункту: Не знаю как сделать это с меньшей стоимостью.. Просто делить все поля (WHERE a / 100000 и отбрасывать дробную часть) мне кажется достаточно затратно... Может есть способ лучше, по маске какой нибудь...
trunc(a, -N), где N - число отбрасываемых справа знаков в числе
...
Рейтинг: 0 / 0
19.10.2015, 12:34
    #39079961
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
Щукина АннаClosiusUPD ко второму пункту: Не знаю как сделать это с меньшей стоимостью.. Просто делить все поля (WHERE a / 100000 и отбрасывать дробную часть) мне кажется достаточно затратно... Может есть способ лучше, по маске какой нибудь...
trunc(a, -N), где N - число отбрасываемых справа знаков в числе

Я вот так попробовал:

Код: sql
1.
2.
SELECT DISTINCT ROUND(marker.levels / 100000000000000000, 0) AS levels_ratio
  FROM marker;



Нормальный ли это путь? Ну мне round подходит тоже, так как числа не больше 4 после запятой, то есть округление в меньшую сторону. Хотя думаю trunc быстрее будет работать.
...
Рейтинг: 0 / 0
19.10.2015, 12:51
    #39079981
qwwq
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
Closius,

осторожно интересуюсь -- тип исходных чисел у вас какой ?
bigint OR numeric

если из интов -- то там целочисленное деление определено.

если numeric -- вместо round надо бы fix -- т.е. или ceil(numeric/numeic) либо trunc(numeric/numeic) -- в зависимости от желаемого поведения для отрицательных.

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

для плавающего основания -- судя по всему тоже -- но только как LIKE и индекса по тексту с varchar_pattern_ops, с лидирующими 0--ми в тексте -- для приведения остатков к фиксированной длине строки.
...
Рейтинг: 0 / 0
19.10.2015, 15:06
    #39080196
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
qwwqClosius,

осторожно интересуюсь -- тип исходных чисел у вас какой ?
bigint OR numeric

если из интов -- то там целочисленное деление определено.

если numeric -- вместо round надо бы fix -- т.е. или ceil(numeric/numeic) либо trunc(numeric/numeic) -- в зависимости от желаемого поведения для отрицательных.

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

для плавающего основания -- судя по всему тоже -- но только как LIKE и индекса по тексту с varchar_pattern_ops, с лидирующими 0--ми в тексте -- для приведения остатков к фиксированной длине строки.

Спасибо. У меня numeric, причем гарантированно положительные.

Вот так думаю оптимальнее всего.

Код: sql
1.
2.
SELECT DISTINCT DIV(marker.levels, 100000000000000000) AS levels_ratio
  FROM marker;
...
Рейтинг: 0 / 0
20.10.2015, 01:33
    #39080756
Ivan Durak
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
ClosiusUPD ко второму пункту: Не знаю как сделать это с меньшей стоимостью.. Просто делить все поля (WHERE a / 100000 и отбрасывать дробную часть) мне кажется достаточно затратно... Может есть способ лучше, по маске какой нибудь...
что затратно? это бд на телефоне чтоли? ты реально думаешь, что в цпу упрешся??????
...
Рейтинг: 0 / 0
20.10.2015, 11:01
    #39080990
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
Ivan DurakClosiusUPD ко второму пункту: Не знаю как сделать это с меньшей стоимостью.. Просто делить все поля (WHERE a / 100000 и отбрасывать дробную часть) мне кажется достаточно затратно... Может есть способ лучше, по маске какой нибудь...
что затратно? это бд на телефоне чтоли? ты реально думаешь, что в цпу упрешся??????

Такой запрос будет приходить от клиента очень часто. Например от одного клиента раз в 10 секунд, штук 20-30 таких запросов. Клиентов несколько миллионов. Данных миллионов 10. Это планируется, по факту может быть хуже. Да, все норм, не упрусь.
...
Рейтинг: 0 / 0
20.10.2015, 11:40
    #39081039
p2.
p2.
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
ClosiusТакой запрос будет приходить от клиента очень часто.часто получать из базы список всех уникальных префиксов?
а как часто этот список меняется?
...
Рейтинг: 0 / 0
20.10.2015, 19:58
    #39081758
Closius
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DISTINCT по первой части числа
p2.ClosiusТакой запрос будет приходить от клиента очень часто.часто получать из базы список всех уникальных префиксов?
а как часто этот список меняется?

Часто меняется. Пользователи могут добавлять или удалять новые объекты когда захотят (в ограниченном кол-ве). Это маркеры на карте. А цифры это код маркера. Карту двигать могут. Каждое движение это новая область запроса (ну на самом деле преусмотрено кширование на клиенте, но всеравно...).
...
Рейтинг: 0 / 0
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / DISTINCT по первой части числа / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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