Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10

Арифметическая "сцепка" чисел в одно число с сохранением уникальности ряда

25.01.2024, 11:10. Показов 2718. Ответов 34

Студворк — интернет-сервис помощи студентам
Приветствую!
По названию сложно понять, как тема относится к SQL. Поясняю.

Есть реальная таблица (на самом деле, это соединение нескольких таблиц, но упрощаю) с 12ю полями, участвующими в группировке (да — вот так и сократить вряд ли получится), а также 2мя полями (кол и сумм) для агрегации и 2мя полями, которые нужно будет "подтянуть" в сгруппированную таблицу.

Разумеется, группировка и, тем более, последующее "подтягивание" по такому количеству полей происходят очень долго.
Появилась идея для ускорения: математически "сцепить" построчно поля для группировки в одно с сохранением уникальности и однозначности ряда — так, чтобы значения рядов "1•2•3", "2•1•3", "3•2•1" (и так далее) сохранили уникальность.

Пока тестирую на простой текстовой сцепке — как показал, но, думаю, что математика будет лучше (и, скорее всего, быстрее), т.к. индекс по числу построить гораздо проще/быстрее, чем по строке (я так думаю, но не уверен).

Предлагаю рассмотреть вариант агрегации в Float (BigInt не хватит для этих целей).
Мои поля, максимальное количество цифр в значении (после "_"). Диапазон значений (в круглых скобках). 0 вместо Null:
Float: (округл. до 2ух знаков после запятой)
Price(-10^15 — 10^15)

Int_10(0 — 9 999 999 999):
Est

Int_7(0 — 9 999 999):
Spr1
Spr2
Spr3

Int_5(0 — 99 999):
Unit

TynyInt:
Type_1(1-4)

Bit(0-1):
B1
B2
B3
B4
Вот эти поля участвуют в группировке и я хочу их заменить одним полем Float.

Алгоритм:

1. Приводим Float к целому, чтобы использовать дробную часть в дальнейших преобразованиях: 100* Round(Field, 2).

2. Четыре Bit-поля преобразуем в одно число до 4ёх знаков: 1000*B1 + 100*B2 + 10*B3 + B4
То есть, вместо "1•0•0•1" получим 1001, а вместо "0•0•1•1" получим 11.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.01.2024, 11:10
Ответы с готовыми решениями:

Как поделить одно двоичное число на другое с сохранением остатка?
Нужно поделить два двоичных числа 100000 и 1101. Для этого написал функцию XOR для строк. Но почему-то происходит переполнение.Подскажите...

Добавление записей с сохранением уникальности, подсчет количества
Здравствуйте. Есть таблица "Статьи" (ID_статьи,Заголовок,Адрес) Есть таблица "Слова" (ID_слова,Текст) Есть связующая...

Insert без дублей (вставка записей в таблицу с сохранением их уникальности)
Как в Firebird организовать вставку записи без дублей? INSERT INTO QUESTTYPE (T_ID, T_NAME) VALUES (id, value);если комбинация (id,...

34
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
29.01.2024, 15:32  [ТС]
Студворк — интернет-сервис помощи студентам
Аватар, большое вам спасибо!
Цитата Сообщение от Аватар Посмотреть сообщение
4 байта на бинари достаточно
а — я понял)) Какой максимальный размер переменной — такой и бинари нужно закладывать, чтобы не обрезал данные

Добавлено через 4 часа 6 минут
Заметки про Float to Binary
Для перевода без потери точности 14ти знаков (как я понял, неважно, десятичные ли они) 8ми байт не хватает, нужно 10
T-SQL
1
2
3
4
5
6
7
8
9
Select Cast(100200300400.12 As Binary(16))  -- 0x000000000E020001CCC754F81C090000
Select Cast(100200300400.12 As Binary(10))  -- 0x000000000E020001CCC754F81C09
Select Cast(100200300400.12 As Binary(8))   -- 0x        0E020001CCC754F8
Select Cast(100200300400.12 As Binary(4))   -- 0x        0E020001
 
Select Cast(10020030040012 As Binary(16))   -- 0x000000000E000001CCC754F81C090000
 
Select Cast(99999999999999 As Binary(16))   -- 0x000000000E000001FF3F7A10F35A0000
Select Cast(99999999999999 As Binary(10))   -- 0x        0E000001FF3F7A10F35A
Подскажите, пожалуйста, ссылку на формулу расчёта — явно же это как-то можно точно рассчитать
0
1307 / 361 / 98
Регистрация: 14.10.2022
Сообщений: 1,105
29.01.2024, 15:55
Jack Famous, вы чем то странным, ей богу, занимаетесь, на мой взгляд.
0
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
29.01.2024, 16:22  [ТС]
uaggster, возможно, но только время покажет.
Я отпишусь по итогу тестов.

Добавлено через 20 минут
Цитата Сообщение от Jack Famous Посмотреть сообщение
Подскажите, пожалуйста, ссылку на формулу расчёта — явно же это как-то можно точно рассчитать
нашёл: математически число бит можно вычислить путем округления в большую сторону логарифма по основанию 2 от заданного числа N плюс 1: Log_2(N+1).
Помним, что логарифм по основанию 2 числа N это показатель степени, в которую нужно возвести 2, чтобы получить N.

То есть, если мне нужно узнать, сколько байт нужно для кодирования числа N, мне нужно вычислить Log_2(N + 1) / 8 и (если я получил НЕцелое число) округлить в большую строну до целого.
Например, для кодирования(перевода в Binary) числа 255 достаточно (Log_2(256) = 8 bit) 1 байта, а вот 256 уже потребует 2 байта.
0
1307 / 361 / 98
Регистрация: 14.10.2022
Сообщений: 1,105
29.01.2024, 17:15
На самом деле, вам же нужен просто некий уникальный маркер n каких-то полей, чтобы осуществлять по нему поиск или группировку?
Ну, возьмите MD5 хэш этих полей.
Он заведомо, для вашей задачи - уникален. И, кстати, довольно компактный, и весь из себя стандартный.
Конечно он тяжеловат, и налету его не особенно повычисляешь, но как калькулируемое persisted поле с индексом по нему - почему нет?

Или, если эти сами n полей - не слишком массивные, можно еще посчитать по ним бинарную хэш-сумму, тоже сделать ее persisted, и построить по ней индекс, include эти самые n полей.
Ну и, собственно, поиск осуществлять по равенству этой хеш - суммы, с дополнительным равенством по полям, и группировку тоже - по хеш-сумме, и по полям.

Я когда-то, очень давно, когда миллион строк считалось солидным размером таблицы, а сто миллионов - чем-то очень большим и невообразимым, делал похожим образом быстрый поиск по ~100 миллионной базе фио, с возможностью оператора ошибиться в нескольких буквах при вводе.
Соответственно, в виде хэша выступали первые буквы фамилии, имени, отчества, а индекс был, см. выше - ФИО + include (фамилия, имя, отчество).
Соответственно, сравнение шло по равенству хеша, и нечеткому поиску (на С написал расширенную хранимую процедуру, считающую дистанцию редактирования) со сравниваемыми полями.
Там, правда не все так просто было. Потому что исказить могли и первые буквы, да и буквосочетания типа КАА, САА - имеют по полмиллиона входов, а чтобы всё это работало с приемлимой скоростью порция должна была быть тысяч 10, но смысл был примерно такой. В реальном режиме времени работало, на пентиум-3 (или что-то типа того).

Так что подход рабочий, но, в целом, в современном мире - не нужный.
Ни место экономить не надо, ни ресурсы процессора.
1
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
29.01.2024, 18:04
Цитата Сообщение от Jack Famous Посмотреть сообщение
8ми байт не хватает, нужно 10
нет
SQL
1
2
SELECT CAST(CAST(100200300400.12 AS FLOAT(53)) AS BINARY(8)) 
SELECT CAST(CAST(100200300400.12 AS FLOAT(53)) AS BINARY(10))
(No column name)
0x423754673F701EB8
0x0000423754673F701EB8
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
30.01.2024, 09:34  [ТС]
Аватар, вы правы, спасибо — не учёл этот момент

uaggster, у меня сложная комплексная задача и я не хочу "с ходу" просить помощи без своих проб. Вот попробую несколько различных вариантов и создам тему не просто с вопросом, а с конкретными вариантами и их таймингами. Вот тогда и обсудим
Спасибо за пример задачи — я бы ещё Collate Cyrillic_General_BIN использовал. Должно быть сильно быстрее
0
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
12.03.2024, 09:58  [ТС]
Снова здравствуйте!
Друзья, подскажите, пожалуйста вот такой момент:
Есть 2 Int поля, но во 2ом значения могут быть только от 1 до 20. В 1ом могут быть сотни миллионов (Int до 2ух с лишним миллиардов).

Могу ли я сделать Binary(5) поле, в которое я сложу ( Cast F1 As Binary(4) ) + ( Cast F2 As Binary(1) )) и быть при этом уверенным, что коллизий и прочих неприятностей не будет?
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
12.03.2024, 13:08
Лучший ответ Сообщение было отмечено Jack Famous как решение

Решение

T-SQL
1
cast(F1 as binary(4)) + cast(cast(F2 as tinyint) as binary(1))
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
12.03.2024, 13:26  [ТС]
invm, приветствую и спасибо!
Я правильно понимаю, что без конверта в более маленький тип я могу получить "обрезанное" число?
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
12.03.2024, 14:09
Лучший ответ Сообщение было отмечено Jack Famous как решение

Решение

C tinyint исключение получишь если там не подходящее число, а без него просто обрежет
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
12.03.2024, 14:31  [ТС]
Аватар, это понятно, но, если я ПРЯМ УВЕРЕН, что в Int-поле будет не более TinyInt (просто начальник для целых только Int использует ) ?
0
 Аватар для Аватар
5393 / 1465 / 513
Регистрация: 31.05.2012
Сообщений: 5,153
12.03.2024, 14:34
Если ПРЯМ то результат аналогичен ) От 255 и получишь ff
0
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
12.03.2024, 14:55  [ТС]
Аватар, ну и отлично. Спасибо!
Цитата Сообщение от Jack Famous Посмотреть сообщение
быть при этом уверенным, что коллизий и прочих неприятностей не будет
я имел в виду именно суммы бинарников. То, что в полях будут только указанные данные — я контролирую.
Но на будущее запомню о такой проверке.
0
1307 / 361 / 98
Регистрация: 14.10.2022
Сообщений: 1,105
12.03.2024, 15:19
Цитата Сообщение от Аватар Посмотреть сообщение
C tinyint исключение получишь если там не подходящее число, а без него просто обрежет
Дык используйте Try_cast.
Что-то типа:
T-SQL
1
cast(F1 as binary(4)) + Coalesce(cast(try_cast(F2 as tinyint) as binary(1)), cast(try_cast(F2 as smallint) as binary(2)), try_cast(F2 as binary(4)))
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
12.03.2024, 16:00  [ТС]
uaggster, не туда разговор зашёл
Но спасибо
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.03.2024, 16:00

Дан ряд чисел от 7 до -7, с шагом 0, 5 (арифметическая прогрессия). Нужно сравнить каждое число с 0. Если <0 то это число *5, если нет, то /5.
Дан ряд чисел от 7 до -7, с шагом 0, 5 (арифметическая прогрессия). Эти числа выводим. Нужно сравнить каждое число с 0. Если &lt;0 то это...

Вычислить одно значение суммы ряда, где аргументом будет число(числа)
Вычислить одно значение суммы ряда, где аргументом будет число(числа), введенное через форму.

Задано натуральное число n. Найти количество натуральных чисел, не превышающих n и не делящихся ни на одно из чисел 2, 3
(Циклы)

Задано натуральное число n. Найти количество натуральных чисел, не превышающих n и не делящихся ни на одно из чисел 2, 3
Задано натуральное число n. Найти количество натуральных чисел, не превышающих n и не делящихся ни на одно из чисел 2, 3, 5

Циклы: Задано натуральное число n. Найти количество натуральных чисел, не превышающих n и не делящихся ни на одно из чисел 2, 3, 5
Завтра зачет не успеваю сделать занимаюсь prologom помогите кому не сложно!!! 1)(Циклы)Задано натуральное число n. Найти количество...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
сукцессия 22. От артефактов к физиологии: калибровка агентной модели грибной сукцессии для воспроизведения сезонной динамики и pH-плато
anaschu 11.07.2026
Аннотация В данной работе представлена калибровка агентной модели динамики грибных сообществ (fungal-succession), направленная на устранение нефизичных артефактов (коллапс биомассы, мгновенное. . .
Сукцессия 20. Война автоботов. Делаем ставки. Лёд против "пш-пш!".
anaschu 11.07.2026
Битва ИИ в ризосфере: Как мы скрестили жесткие ОДУ, закон Фика и «подземный шантаж» Уважаемые коллеги! Хочу поделиться уникальным опытом ведения междисциплинарной компьютерной разработки. Прямо. . .
Сукцессия 19. Какие выводы я сделал из модели? Часть 2.Внутримикоризный стехиометрический буфер и хроно-дискретные зоны экспансии
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования
Сукцессия 18. Какие выводы я сделал из войны грибов с деревьями? Часть 1- рассказ и немного про термины
anaschu 11.07.2026
Био-Инженерный Ликбез: Архитектура Модели Ризосферы Математический аппарат моделирования Система ОДУ описывает динамику изменения массы различных компонентов системы во времени. Ключевой. . .
Просветление в 5 секунд
kumehtar 10.07.2026
Андрей Веретенников выдал фразу недавно: "Вам не обязательно кем-то себя считать"
Эксперимент с картинкой-обложкой на CodinGame
Adler 10.07.2026
Решил на днях провести эксперимент. У меня есть аккаунт на CodinGame, ТОП-3 по РФ среди 2200 участников (в разделе соревнования по программированию ИИ-ботов). Там есть обложка, куда можно влепить. . .
GitDOS: Когда я решил скрестить MS-DOS, GitHub и Claude
MaGz GoLd 08.07.2026
Привет, Киберфорум! Хочу поделиться своим проектом, который, надеюсь, вас заинтересует. GitDOS — это веб-приложение, которое позволяет запускать DOS в браузере с тремя крутыми фичами: диски живут в. . .
Учебный мини "цифровой двойник" = (Сервер = Java + Flask_питон )+(3D = Гугловскаая 4T nvideo + google colab) +( WMS = Odoo на Docker)
anaschu 07.07.2026
Увидел в требованиях к вакансии создателя имитационных моделей связку (REst + Api + WMS + Anylogic + питон + 3D Nvideo), и решил посмотреть, что это такое. Из этого всего я работал более менее. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru