Выразить число как строку и дату как строку в запросе

Опубликовал Сергей (ildarovich) в раздел Программирование - Практика программирования

Предлагается новый и более компактный метод преобразования даты и числа в строку в запросе

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

Основной проблемой рассматриваемого преобразования в строку является выделение каждого конкретного разряда исходного числа. Например, число 123 состоит из трех разрядов. Пусть разряды нумеруются справа налево, начиная с нуля. Разряды отличаются весом: нулевой разряд в десятичной позиционной системе счисления имеет вес 1, первый – 10, второй – 100 и так далее. Для выделения каждого разряда требуется найти целое от деления числа на вес разряда, а затем – остаток от деления полученного целого на 10. Первый (второй слева) разряд, таким образом, получится так: 123 разделим на 10, получим 12,3. Затем возьмем целое, получим  12. Затем найдем остаток от деления на 10, получим 2 – искомый первый (второй слева) разряд. Буквальная запись этих выражений в запросе получается очень и очень громоздкой, но существует другой путь.

Этот путь заключается в использовании для нахождения остатка от деления пары функций: СЕКУНДА и ДОБАВИТЬКДАТЕ. Дело в том, что функция СЕКУНДА фактически является функцией остатка от деления на 60 числа секунд, прошедшего с начала времен. Чтобы превратить ее в функцию расчета остатка от деления на 10 достаточно считать секунды шестерками. То есть требуемая функция будет записываться так:

СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Икс * 6) ) / 6

Эта функция выделяет самый правый (нулевой) разряд числа Икс. Чтобы выделить первый разряд, нужно использовать функцию

СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Икс * 0.6) ) / 6

А чтобы выделить второй – функцию

СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Икс * 0.06) ) / 6

И так далее. Множитель 60 позволяет выделить разряд десятых долей, 600 – сотых и так далее.

Ограничением рассмотренного подхода является максимальное число секунд при работе с датами. Оно таково, что мы можем выделить не более 10-ти десятичных знаков в числе. Если число значащих знаков больше, исходное число потребуется предварительно разделить на две части «обычным» способом с использованием операции ВЫРАЗИТЬ КАК.

Приведем пример запроса для случая ЧИСЛО(8, 2)

ВЫБРАТЬ
	ПОДСТРОКА("0123456789", &Число / 10000000 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.000006)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.00006)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.0006)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.006)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.06)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.6)) / 6 + 1, 1)
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 6)) / 6 + 1, 1)
	+ "." 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 60)) / 6 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 600)) / 6 + 1, 1) КАК Строка

Чтобы сделать запись чуть более короткой, две постоянные - цепочку цифр «0123456789» и начало времен можно вынести во вложенный запрос

ВЫБРАТЬ
	ПОДСТРОКА(Ц, &Число / 10000000 + 1, 1) 
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.000006)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.00006)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.0006)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.006)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.06)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 0.6)) / 6 + 1, 1)
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 6)) / 6 + 1, 1)
	+ "." 
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 60)) / 6 + 1, 1) 
	+ ПОДСТРОКА(Ц, СЕКУНДА(ДОБАВИТЬКДАТЕ(О, СЕКУНДА, &Число * 600)) / 6 + 1, 1) КАК Строка
ИЗ (ВЫБРАТЬ "0123456789" Ц, ДАТАВРЕМЯ(1, 1, 1) О) КАК Константы

Аналогичным образом можно преобразовать число в строку в двоичной системе счисления. Вот запрос для записи в виде строки восьми младших двоичных разрядов заданного числа:

ВЫБРАТЬ
	  ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 128)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 64)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 32)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 16)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 8)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 4)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30 / 2)) / 30 + 1, 1)
	+ ПОДСТРОКА("01", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 30)) / 30 + 1, 1) КАК Строка

 

Побочным следствием использованных закономерностей является то, что выражение

СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Икс * 30) ) = 0

можно использовать в запросе для проверки четности числа Икс.

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

ВЫБРАТЬ
	ПОДСТРОКА("0123456789", ДЕНЬ(&Дата) / 10 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, 6 * ДЕНЬ(&Дата))) / 6 + 1, 1) 
	+ "/" 
	+ ПОДСТРОКА("0123456789", МЕСЯЦ(&Дата) / 10 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, 6 * МЕСЯЦ(&Дата))) / 6 + 1, 1) 
	+ "/" 
	+ ПОДСТРОКА("0123456789", ГОД(&Дата) / 1000 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 0.06)) / 6 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 0.6)) / 6 + 1, 1) 
	+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 6)) / 6 + 1, 1) КАК Строка

Как видно, используемые для преобразования в строку выражения довольно просты и компактны, особенно если сравнить их с тем, что приходилось использовать до сих пор.

См. также

Комментарии
1. Алексей Рожнятовский (spetzpozh) 23.02.15 00:42 Сейчас в теме
Моя обычная реакция на публикации Маэстро - посмотрел, почесал репу, плюсанул и пошел дальше )))
kolessov_a; sstas007; sergio199; rpgshnik; Mails79; Anchoret; корум; veretennikoff; h00k; swimdog; flagma; NazarovV; orfos; hornet_X; Ananas_Zar; trumanl; MaxDavid; xCorsair; DrAku1a; _also; bds22; smit1c; Йожкин Кот; necropunk; lidersoft2; monkbest; Evil Beaver; slavap; Поручик; bulpi; Nuobu; Dmirily; DoctorRoza; iov; Tavalik; Uncore; pavlov_dv; w-divin; Makushimo; spezc; dj_serega; +41 Ответить
2. Ololo Anonim (ololoanonim) 3 23.02.15 11:20 Сейчас в теме
Выглядит весьма круто =)
3. Павел Чистов (GROOVY) 2266 23.02.15 13:41 Сейчас в теме
Фундаментально выглядит. Но нафига? Никогда не понимал, зачем это нужно.
Запрос оперирует данными, нужно красивое представление - для этого есть другие механизмы.
tsmult; h00k; sergey512; monkbest; Nuobu; DoctorRoza; Dmitryiv; +7 2 Ответить 1
4. Сергей (ildarovich) 4966 23.02.15 15:53 Сейчас в теме
(3) GROOVY, вот небольшой перечень ссылок, который показывает, насколько часто встречается этот вопрос:
Преобразование строки в число/числа в строку в запросе
Как уже в запросе объединить число и строку?
Сложение строк в запросе
Дата в строку в запросе..
Как преобразовать дату в строку в запросе ?
v8: Операции преобразования Число в Строку и обратно в запросах
Вычисление строки в запросе.
Другие можно получит поиском "1С запрос дата число в строку"
Возможно, в половине случаев здесь действительно неправильно поставлена задача и лучше производить преобразование вне запроса.
Но, думаю, есть и случаи обоснованной необходимости таких преобразований.

Немного пофантазировав, можно привести такие примеры:
1) Проверить контрольные соотношения в разрядах ИНН, SSC, EAN (потребуется преобразование строки в число, выделение и сложение разрядов числа, расчет остатка);
2) Сформировать номера договоров, включающие даты;
3) Сформировать номера накладных, включающих даты;
4) Сформировать артикулы, включающие размер, вес или другие числовые характеристики товара;
5) Проверить набор признаков, закодированных в одном числе;
6) Найти пропущенные номера документов запросом;
7) Выделить (внести) вес из (в) штрих-кода весового товара.

Разумеется, здесь имеется ввиду, что формирование и проверка делаются не для вывода, а для последующего использования внутри пакетного запроса: поиска, сравнения, вычисления, группировки.

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

Кроме того, здесь должен быть отдельно интересен прием компактной записи расчета остатка. Разложив 60 на множители, получим 2х2х3х5. Это значит, что через СЕКУНДА можно рассчитать остаток от деления на 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60. А через функцию ЧАС (24 = 2х2х2х3) еще на 8 и 24.
sergio199; sss_russian; CratosX; iov; AlmazBur01; ugroblin; Dolly_EV; Оля_; BalyunovVV; Gesperid; +10 Ответить
5. Руслан Ибрагимов (break) 27 24.02.15 10:35 Сейчас в теме
а без значащихся нулей перед числами можно соорудить?
6. Сергей (ildarovich) 4966 24.02.15 11:17 Сейчас в теме
(5) break, можно, если интерес не праздный. Приведите пример практической задачи - сделаю.
7. Марина Чирина (chmv) 26.02.15 12:55 Сейчас в теме
А попроще. Может быть когда-нибудь и 1с это реализует
8. Борис Скворцов (gaglo) 27.02.15 09:58 Сейчас в теме
Большое спасибо за идею использования функции СЕКУНДА для получения остатка от деления. (Кажется мне, что простая проверка четности и другой кратности в запросе надобна чаще, чем перевод числа в строку.)
9. Марина Чирина (chmv) 27.02.15 10:07 Сейчас в теме
8 Как раз Вы не правы, чаще перевод даты в строку
10. Сергей Ожерельев (Поручик) 3536 08.03.15 21:26 Сейчас в теме
На статьи автора у меня тоже реакция одна - почитал, плюс, порадовался, что есть люди с фундаментальным образованием. Сам бы ни за что не написал.
h00k; Evil Beaver; +2 Ответить
11. Антон Антонов (monkbest) 28 17.03.15 11:04 Сейчас в теме
Я правильно понимаю, что строки полученные Вашим методом, потом можно складывать?

Потому что такой вот запрос вернет число как строку неограниченной длины
ВЫБРАТЬ
	ВзаиморасчетыССотрудниками.СуммаВзаиморасчетов,
	ПРЕДСТАВЛЕНИЕ(ВзаиморасчетыССотрудниками.СуммаВзаиморасчетов) КАК СуммаВзаиморасчетов1
ИЗ
	РегистрНакопления.ВзаиморасчетыССотрудниками КАК ВзаиморасчетыССотрудниками
ГДЕ
	ВзаиморасчетыССотрудниками.Сотрудник = &Сотрудник
...Показать Скрыть
12. Сергей (ildarovich) 4966 17.03.15 13:13 Сейчас в теме
(11) monkbest, да, можно складывать.
В вашем запросе "представление" это строка, которая формируется не в СУБД, а платформой в процессе постобработки запроса. Также как "итоги", например. Поэтому "представление" вы никак в самом запросе далее использовать не можете.
А строки, полученные в приведенных выражениях, можно использовать в запросе дальше. По ним можно группировать, соединять и прочее. Это обычное выражение языка запросов, хотя и несколько громоздкое.
13. Александр Милютин (sanfoto) 465 23.03.15 07:04 Сейчас в теме
(12) ildarovich,
В вашем запросе "представление" это строка, которая формируется не в СУБД, а платформой в процессе постобработки запроса.


так то в принципе и 1С запросы - не чисто SQL запросы, а реляционно-подобные "объектные запросы к ВИРТУАЛЬНОЙ объектной модели"...
т.е. в процессе выполнения такого "объектного запроса" - генирится много дополнительного SQL кода для получения этих объектов..
К чему я это пишу - к тому что повальное увлечение переноса абсолютно всего кода в "1С запрос" - совсем не всегда оправдано на платформе "1С". На практике часто бывает быстрей отрабатывает(и пишется..) код с циклами с использованием 1С объектов "ТаблицаЗначений" и т.д.
14. Сергей (ildarovich) 4966 23.03.15 16:48 Сейчас в теме
(13) sanfoto, я противник крайностей. "Повальным увлечениям" стараюсь не поддаваться. Всегда нужно сравнивать время решения задачи запросом и кодом. Но, чтобы сравнивать решения, нужно их иметь. Вот тут и приведено возможное решение в запросе. Не чтобы безусловно использовать, а чтобы сравнить и выбрать. Таким образом у нас расширяется пространство возможностей, а уж выбор каждый делает сам в зависимости от конкретной задачи.
fishca; mikele_bes; ABudnikov; premier; realsevere; UniversaLL; sanfoto; +7 Ответить
15. Allexey (alex_4x) 72 25.08.15 13:01 Сейчас в теме
Yakud3a; NeLenin; sergio199; SergeyTerentyev; корум; IlyaSR; slawanix; AfroditaS; smaximaa; madonov; CratosX; NeviD; Cruciann; Winstoncuk; Nelli_A86; SavR11; sanfoto; Dementor; fvadim; Ali1976; hotey; Sergey_1c; ditp; tarassov; +24 Ответить 1
16. Сергей (ildarovich) 4966 26.08.15 13:08 Сейчас в теме
(15) alex_4x, картинку сами рисовали (редактировали) или взяли откуда?
17. Allexey (alex_4x) 72 26.08.15 13:34 Сейчас в теме
(16) ildarovich, Это Дилберт! Они очень наслышаны о нашей 1С :-)
18. Serj (Serj1C) 461 13.01.16 13:18 Сейчас в теме
Связываться с датами для усечения дробной части? не накладно?
Может попробовать функцию Выразить(&Число-0.49 как Число(15,0)) ?
19. Сергей (ildarovich) 4966 13.01.16 14:46 Сейчас в теме
(18) Serj1C, в этом случае у меня получалось более громоздкое выражение. Поскольку для выделения одной цифры целое нужно было находить дважды. А по затратам времени, думаю, результаты должны быть примерно одинаковыми. То есть при примерно равных затратах времени выбираем меньшую громоздкость. Такое обоснование.
20. Георгий Скворцов (Sgeor) 14.01.16 11:24 Сейчас в теме
Пригодился этот метод для таблиц из внешней БД.
Заметил один момент: в десятках выводились значения на единицу больше (например, вместо значения "10307" выводилось "10317").
Проблема решилась после того, как убрал "+1" из "/ 6 + 1" в вычислении десятков. Вот фрагмент:
ПО (customfieldvalue.STRINGVALUE = "10" 
+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ВЫРАЗИТЬ(customfieldoption.ID * 0.06 КАК ЧИСЛО(18, 0)))) / 6 + 1, 1) 
+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ВЫРАЗИТЬ(customfieldoption.ID * 0.6 КАК ЧИСЛО(18, 0)))) / 6, 1) 
+ ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, customfieldoption.ID * 6)) / 6 + 1, 1))

Так что лучше перепроверить перед использованием этого метода.
Но мне все-равно очень пригодилось, спасибо.
21. Сергей (ildarovich) 4966 14.01.16 15:12 Сейчас в теме
(20) Sgeor, в тексте метода, приведенном в статье, никакого ВЫРАЗИТЬ нет. Этот оператор в этом случае не нужен, он лишний. То, что написано в (20) у меня совсем никак не работает.
Если же записать в точности так, как написано в статье:
ВЫБРАТЬ
	10307 КАК Id
ПОМЕСТИТЬ customfieldoption
;
ВЫБРАТЬ
	ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Id * 0.0006)) / 6 + 1, 1)
+ 	ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Id * 0.006)) / 6 + 1, 1)
+ 	ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Id * 0.06)) / 6 + 1, 1)
+ 	ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Id * 0.6)) / 6 + 1, 1)
+ 	ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Id * 6)) / 6 + 1, 1)
ИЗ
	customfieldoption КАК customfieldoption
...Показать Скрыть

то результат будет совершенно верный: "10307"
22. Георгий Скворцов (Sgeor) 14.01.16 21:16 Сейчас в теме
(21) ildarovich, не при чем тут вообще "ВЫРАЗИТЬ" - это кусок давнишнего изврата и мракобесия=)
Тем не менее, я залез уже в консоль перепроверить и на сей раз вбил все чисто:
ВЫБРАТЬ
    customfieldoption.ID КАК До,
    "10" + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, customfieldoption.ID * 0.06)) / 6 + 1, 1)
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, customfieldoption.ID * 0.6 )) / 6 + 1, 1)
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, customfieldoption.ID * 6)) / 6 + 1, 1) КАК После
ИЗ
    ВнешнийИсточникДанных.JiraBasina.Таблица.customfieldoption КАК customfieldoption
...Показать Скрыть


Результат:
До----|--После
10300 | 10300
10301 | 10301
10302 | 10302
10303 | 10303
10304 | 10304
10305 | 10315
10306 | 10316
10307 | 10317
10308 | 10318
10309 | 10319

В итоге, если число в предыдущем разряде > 4, то прибавляется ненужная 1. Когда избавился от "+1" в вычислении десятков, все встало на свои места. Когда избавился от "+1" во всех разрядах, снова получил бред. А по твоему коду в (21) все в порядке. Магия.
Думается, что с ID-шниками в базе что-то странное? Нет - число как число.
23. Сергей (ildarovich) 4966 15.01.16 12:47 Сейчас в теме
(22) Sgeor, я, кажется, понял в чем дело. Есть правило определение точности результатов арифметических операций в запросе в зависимости от точности операндов. Они описаны в статье: Разрядность результатов выражений и агрегатных функций в языке запросов. Видимо, срабатывание этого правила приводит к необходимости привести результат customfieldoption.ID * 0.6 к целому типу! В результате производится не отбрасывание дробной части (как задумано в данном в статье выражении), а округление. Поэтому, видимо, нужно предварительно привести операнд к нужному типу, например, ВЫРАЗИТЬ(Id КАК Число(15, 1)).
24. Наталья Селезнева (selenat) 01.02.16 12:02 Сейчас в теме
Добрый день. В базах на sql этот запрос нормально отрабатывает, а в базе на постгри - вылетает с ошибкой. Причем даже если делаю ПОДСТРОКА(""0123456789"", ВЫРАЗИТЬ(СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, &Число * 0.06)) / 6 + 0.5 КАК ЧИСЛО(1, 0)), 1) (+0.5 использую, так как ВЫРАЗИТЬ округляет число, а не отбрасывает дробную часть)
как этому можно помочь?
25. Сергей (ildarovich) 4966 01.02.16 12:33 Сейчас в теме
(24) selenat, а платформа какая? Вообще с Postgre проблемы могут быть, буду разбираться, но быстро не обещаю.
26. Наталья Селезнева (selenat) 01.02.16 13:33 Сейчас в теме
27. Олег (olbu) 21.10.16 16:46 Сейчас в теме
Не могу сообразить, как имея таблицу дат в запросе и вот этот запрос
ВЫБРАТЬ
    ПОДСТРОКА("0123456789", ДЕНЬ(&Дата) / 10 + 1, 1) 
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, 6 * ДЕНЬ(&Дата))) / 6 + 1, 1) 
    + "/" 
    + ПОДСТРОКА("0123456789", МЕСЯЦ(&Дата) / 10 + 1, 1) 
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, 6 * МЕСЯЦ(&Дата))) / 6 + 1, 1) 
    + "/" 
    + ПОДСТРОКА("0123456789", ГОД(&Дата) / 1000 + 1, 1) 
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 0.06)) / 6 + 1, 1) 
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 0.6)) / 6 + 1, 1) 
    + ПОДСТРОКА("0123456789", СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, ГОД(&Дата) * 6)) / 6 + 1, 1) КАК Строка
...Показать Скрыть


получить таблицу дат в строковом выражении?
28. Сергей (ildarovich) 4966 24.10.16 13:36 Сейчас в теме
(27) olbu, вам нужно написать запрос примерно такого вида:
ВЫБРАТЬ <СложноеВыражениеИзСтатьиГДЕПараметр&ДатаЗамененНаНужноеИмяПоляТаблицыДат> КАК ДатаВСтроковомВыражении ИЗ ТаблицаДатВЗапросе

Другими словами, в том поле, где требуется строковое представление даты, требуется записать сложное выражение из статьи, где вместо параметра &Дата указать имя поля таблицы, из которой выбираются даты.
29. Игорь (user633312_i_vi) 01.11.16 20:34 Сейчас в теме
ПОДСТРОКА("01020304050607080910111213141516171819202122232425262728293­031",ДЕНЬ(&Дата)*2-1,2)+"."
+ПОДСТРОКА("010203040506070809101112",МЕСЯЦ(&Дата)*2-1,2)+".201"
+ПОДСТРОКА("0123456789",ГОД(&Дата)-2010+1,1) КАК СтрДата
// Тоже не ахти но ...
DarkAn; jmi; +2 Ответить 1
30. Сергей (ildarovich) 4966 02.11.16 11:02 Сейчас в теме
(29) user633312_i_vi, хороший вариант. С месяцами вообще все хорошо, с годом - плохо.Дни - зависит от вкуса. Лично мне нравится. Возможно, стоит комбинировать в одном выражении оба этих подхода.
31. Владислав Матвеев (Amur_MVS) 5 22.05.17 13:12 Сейчас в теме
Оставьте свое сообщение