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

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

Приведены и прокомментированы запросы, помогающие решать указанные задачи в составе пакетных запросов. Отличием от других известных решений является простая структура, относительная компактность, высокие быстродействие и устойчивость к ошибкам исходных данных. Применяется техника искусственных таблиц, изначально упомянутая в статье "Порождающий запрос" [http://infostart.ru/public/90367/]

1. Преобразование таблицы строк в таблицу целых чисел. 

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


    "ВЫБРАТЬ Дано.НомерСтроки, Дано.Строка
    |ПОМЕСТИТЬ Дано
    |ИЗ &Дано КАК Дано
    |;
    |ВЫБРАТЬ 0 С,    1 КАК П
    |ПОМЕСТИТЬ Р16
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  1, 10
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  2, 100
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  3, 1000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  4, 10000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  5, 100000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  6, 1000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  7, 10000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  8, 100000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  9, 1000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 10, 10000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 11, 100000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 12, 1000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 13, 10000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 14, 100000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 15, 1000000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 16, 10000000000000000
    |;
    |ВЫБРАТЬ СУММА(А.П * Б.С) / МИНИМУМ(А.П) КАК Ответ
    |ИЗ Дано, Р16 КАК А, Р16 КАК Б
    |ГДЕ    Б.С < 10 И ПОДСТРОКА(Дано.Строка, 17 - А.С, 1) = ПОДСТРОКА(""0123456789"", Б.С + 1, 1)
    |СГРУППИРОВАТЬ ПО Дано.НомерСтроки"

В пакете всего три запроса.

Первый запрос пакета выполняет загрузку таблицы значений, содержащей исходные строковые представления чисел, и помещает ее в таблицу «Дано» с колонками «НомерСтроки» и "Строка". Второй запрос пакета формирует искусственную таблицу, содержащую номера позиций и их вес в десятичной позиционной системе счисления. Счет позиций идет справа налево.

Вся основная работа по преобразованию строки в число выполняется в последнем, третьем запросе пакета. В этом запросе таблица «Дано» умножается на таблицу весов позиций Р16 (КАК А) и еще раз на таблицу Р16 (КАК Б). В последней используется только первые десять строк первой колонки  для прохода по номерам всех цифр строки «0123456789». Условие «ГДЕ» отбирает записи, в которых цифры в исходной строке и строке «0123456789» совпадают в позиции, определяемой для исходной строки строкой таблицы весов А и для строки цифр – строкой таблицы номеров цифр Б. Это дает возможность определить искомое число как сумму произведений веса позиции на номер цифры. При этом группировка идет  по строкам таблицы «Дано».

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

Работа данного запроса иллюстрируется схемой на фиг.1, где показано преобразование в число строки «4957379257».

Схема работы последнего запроса пакета 

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

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

2. Преобразование таблицы строк в таблицу дробных чисел.

Преобразование таблицы строк в таблицу дробных чисел можно выполнить следующим пакетным запросом. 

    "ВЫБРАТЬ Дано.НомерСтроки, Дано.Строка
    |ПОМЕСТИТЬ Дано
    |ИЗ &Дано КАК Дано
    |;
    |ВЫБРАТЬ 0 С,    1 КАК П
    |ПОМЕСТИТЬ Р16
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  1, 10
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  2, 100
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  3, 1000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  4, 10000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  5, 100000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  6, 1000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  7, 10000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  8, 100000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ  9, 1000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 10, 10000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 11, 100000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 12, 1000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 13, 10000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 14, 100000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 15, 1000000000000000
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 16, 10000000000000000
    |;
    |ВЫБРАТЬ СУММА(А.П * Б.С * ВЫБОР КОГДА ПОДСТРОКА(Строка, 1, 17 - А.С) ПОДОБНО ""%.%"" ТОГДА 10 ИНАЧЕ 1 КОНЕЦ)
    |/ МИНИМУМ(ВЫБОР КОГДА НЕ ПОДСТРОКА(Строка, 1, 17 - А.С) ПОДОБНО ""%.%"" ТОГДА А.П ИНАЧЕ 100000000000000000 КОНЕЦ) КАК Ответ
    |ИЗ Дано КАК Дано, Р16 КАК А, Р16 КАК Б
    |ГДЕ    Б.С < 10 И ПОДСТРОКА(Строка, 17 - А.С, 1) = ПОДСТРОКА(""0123456789"", Б.С + 1, 1)
    |СГРУППИРОВАТЬ ПО Дано.НомерСтроки"


Данный пакетный запрос отличается от предыдущего особой обработкой позиций, находящихся справа от первой десятичной точки. Такие позиции выделяются с использованием оператора ПОДОБНО. Проверяется подобие подстроки, заканчивающейся в данной позиции и шаблона "%.%". Для позиций, находящихся правее точки, применяется дополнительный множитель 10. Также меняется определение нормализующего делителя, который находится как минимум веса позиций, не находящихся правее первой точки.

3. Преобразование таблицы строк в таблицу целых чисел с "выращиванием" таблицы весов.

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


    "ВЫБРАТЬ Дано.НомерСтроки, Дано.Строка
    |ПОМЕСТИТЬ Дано
    |ИЗ &Дано КАК Дано
    |;
    |ВЫБРАТЬ 0 КАК С, 1 КАК П
    |ПОМЕСТИТЬ Р1
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 1, 10
    |;
    |ВЫБРАТЬ    А.С + Б.С КАК С, МАКСИМУМ(А.П * Б.П) КАК П
    |ПОМЕСТИТЬ Р2
    |ИЗ Р1 КАК А, Р1 КАК Б
    |СГРУППИРОВАТЬ ПО А.С + Б.С
    |;
    |ВЫБРАТЬ    А.С + Б.С КАК С, МАКСИМУМ(А.П * Б.П) КАК П
    |ПОМЕСТИТЬ Р4
    |ИЗ Р2 КАК А, Р2 КАК Б
    |СГРУППИРОВАТЬ ПО А.С + Б.С
    |;
    |ВЫБРАТЬ    А.С + Б.С КАК С, МАКСИМУМ(А.П * Б.П) КАК П
    |ПОМЕСТИТЬ Р8
    |ИЗ Р4 КАК А, Р4 КАК Б
    |СГРУППИРОВАТЬ ПО А.С + Б.С
    |;
    |ВЫБРАТЬ    А.С + Б.С КАК С, МАКСИМУМ(А.П * Б.П) КАК П
    |ПОМЕСТИТЬ Р16
    |ИЗ Р8 КАК А, Р8 КАК Б
    |СГРУППИРОВАТЬ ПО А.С + Б.С
    |;
    |ВЫБРАТЬ СУММА(А.П * Б.С) / МИНИМУМ(А.П) КАК Ответ
    |ИЗ Дано, Р16 КАК А, Р16 КАК Б
    |ГДЕ    Б.С < 10 И ПОДСТРОКА(Дано.Строка, 17 - А.С, 1) = ПОДСТРОКА(""0123456789"", Б.С + 1, 1)
    |СГРУППИРОВАТЬ ПО Дано.НомерСтроки"


В этом пакетном запросе семь подзапросов.

Первый запрос, как всегда, осуществляет ввод данных.

Во втором запросе пакета определяется таблица Р1 для позиций 0 и 1 с весом 1 и 10. Затем в третьем запросе перемножением Р1 на себя получается таблица Р2, содержащая позиции 0, 1 и 2 с весом 1, 10 и 100. В четвертом запросе перемножением Р2 на себя получается  таблица Р4. Схема этого умножения показана на фиг.2. В пятом запросе пакета Р4 умножается на себя и получается Р8, в шестом Р8 умножается на себя и получается Р16. При перемножении используется группировка по сумме номера позиции с агрегацией в виде максимума произведения весов позиций. Поскольку число позиций каждый раз увеличивается вдвое,  для выращивания итоговой таблицы из 17 строк понадобилось всего четыре запроса. Похожая «математика» используется в статье "Транзитивное замыкание запросом" [http://infostart.ru/public/158512/]. Все получаемые таблицы изображены на фиг.3.

Схема умножения таблиц при выращивании таблицы весов

Рост таблиц весов

4. Преобразование таблицы строк в таблицу дат. 

Преобразование таблицы строк вида «ГГГГММДД» в таблицу дат можно выполнить следующим пакетным запросом.

    "ВЫБРАТЬ Дано.НомерСтроки, Дано.Строка
    |ПОМЕСТИТЬ Дано
    |ИЗ &Дано КАК Дано
    |;
    |ВЫБРАТЬ 0 Х, 0 Д, 0 М, 1000 Г
    |ПОМЕСТИТЬ Формат
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 1, 0, 0, 100
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 2, 0, 0, 10
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 3, 0, 0, 1
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 4, 0, 10, 0
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 5, 0, 1, 0
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 6, 10, 0, 0
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 7, 1, 0, 0
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 8, 0, 0, 0
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 9, 0, 0, 0
    |;
    |ВЫБРАТЬ ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1,1,1,0,0,0),ДЕНЬ,СУММА(А.Д*Б.Х)-1),МЕСЯЦ,СУММА(А.М*Б.Х)-1),ГОД,СУММА(А.Г*Б.Х)-1) КАК Ответ
    |ИЗ Дано, Формат КАК А, Формат КАК Б
    |ГДЕ    А.Х < 8 И Б.Х < 10 И ПОДСТРОКА(Дано.Строка, А.Х + 1, 1) = ПОДСТРОКА(""0123456789"", Б.Х + 1, 1)
    |СГРУППИРОВАТЬ ПО Дано.НомерСтроки"

 

 

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

Во втором запросе определяется временная таблица "Формат" с четырьмя колонками. В колонке "Х" записывается номер позиции в строке, начиная с нуля слева направо, в колонке "Д" - вес позиции при подсчете числа дней, "М" - месяцев, "Г" - лет. В последнем запросе вычисляется сумма произведений каждой колонки на номер цифры, находящейся в соответствующей позиции. Далее эти суммы произведений как число лет, месяцев и дней добавляются функцией добавить к дате сначала к "нулевому дню" '00010101', потом к результату первого добавления, а затем к результату второго. Это и дает в итоге искомую дату.

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

 

5. Преобразование таблицы строк в таблицу дат с "выращиванием" таблицы позиций.

Текст данного запроса выглядит следующим образом. 


    "ВЫБРАТЬ Дано.НомерСтроки, Дано.Строка
    |ПОМЕСТИТЬ Дано
    |ИЗ &Дано КАК Дано
    |;
    |ВЫБРАТЬ    0 КАК Х
    |ПОМЕСТИТЬ Р1
    |ОБЪЕДИНИТЬ ВЫБРАТЬ 1
    |;
    |ВЫБРАТЬ    А.Х + 2 * Б.Х КАК Х
    |ПОМЕСТИТЬ Р2
    |ИЗ Р1 КАК А, Р1 КАК Б
    |;
    |ВЫБРАТЬ    А.Х + 4 * Б.Х КАК Х
    |ПОМЕСТИТЬ Р4
    |ИЗ Р2 КАК А, Р2 КАК Б
    |;
    |ВЫБРАТЬ ДОБАВИТЬКДАТЕ(
    |           ДОБАВИТЬКДАТЕ(
    |               ДОБАВИТЬКДАТЕ(
    |                   ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
    |                   , ДЕНЬ
    |                   , СУММА(ВЫБОР А.Х КОГДА 7 ТОГДА 1 КОГДА 6 ТОГДА 10 КОНЕЦ * Б.Х) - 1
    |               )
    |               , МЕСЯЦ
    |               , СУММА(ВЫБОР А.Х КОГДА 5 ТОГДА 1 КОГДА 4 ТОГДА 10 КОНЕЦ * Б.Х) - 1
    |           )
    |           , ГОД
    |           , СУММА(ВЫБОР А.Х КОГДА 3 ТОГДА 1 КОГДА 2 ТОГДА 10 КОГДА 1 ТОГДА 100 КОГДА 0 ТОГДА 1000 КОНЕЦ * Б.Х) - 1
    |       ) КАК Ответ
    |ИЗ Дано, Р4 КАК А, Р4 КАК Б
    |ГДЕ    А.Х < 8 И Б.Х < 10 И ПОДСТРОКА(Дано.Строка, А.Х + 1, 1) = ПОДСТРОКА(""0123456789"", Б.Х + 1, 1)
    |СГРУППИРОВАТЬ ПО Дано.НомерСтроки"


В отличие от предыдущих запросов, здесь не используется определение веса позиций заранее. Веса позиций определяются в ходе суммирования. Поэтому заранее достаточно вырастить таблицу позиций цифр Р16. Это делается также как в статье "Порождающий запрос" [http://infostart.ru/public/90367/] из таблицы Р2, содержащей 0 и 1, задаваемой вторым запросом пакета. Сначала Р2 умножается на себя и без группировок получается Р4 из четырех строк 0, 1, 2 и 3 (третий запрос), затем Р4 умножается на себя и получается Р16 из 16-ти строк 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 и 15 (четвертый запрос пакета). Умножение матрицы Р4 на себя в четвертом запросе показано в виде схемы фиг.4.

Схема умножения таблиц при выращивании таблицы позиций

Вся основная работа выполняется в пятом запросе. Год в виде числа, месяц в виде числа и день в виде числа получаются как сумма произведений номера цифры на вес позиции. Вес позиций определяется для каждого элемента даты отдельно при помощи оператора «ВЫБОР». Определенные год, месяц и день подставляются в функции «ДОБАВИТЬКДАТЕ», что и дает в итоге искомую дату.

6. Преобразование таблицы строк в таблицу дат со временем по формату, задаваемом параметром запроса. 


При анализе запроса 4 можно увидеть, что формат даты задается таблицей весов позиций года, месяца и дня «Формат». Эту таблицу можно дополнить колонками для часов, минут и секунд. При различном заполнении этой таблицы можно анализировать даты, представленные в самом различном формате. Примеры заполнения таблицы "Формат" для различных форматов даты приведены на фиг.5.

Содержание таблицы  

В связи с эти возникает идея: А если вообще не задавать таблицу "Формат" заранее, а построить ее внутри запроса путем анализа текстового параметра "&Формат", передаваемого в запрос и определяющего формат даты. Тогда запрос станет чрезвычайно гибким и универсальным. На этой идее построен шестой запрос.

Текст данного запроса, отличающейся универсальностью за счет управления преобразованием с помощью строкового параметра "&Формат", можно посмотреть в прилагаемой к статье обработке. Дополнительным бонусом, скачавшим обработку, будут примеры очень уместного использования (как кажется) функции "НовыйЗапрос" [http://infostart.ru/public/163853/] в модуле обработки. На скриншотах, прилагаемых к статье,  приведены примеры преобразований при задании различных форматов даты. В определении формата использованы русские букы "Г", "М", "Д", "Ч", "Н" и "С". Важно, что позиции минут обозначены не маленькой русской "м", а русской "н", поскольку в запросе нет возможности различить регистр символов. Для заполнения незначащих позиций можно использовать любые другие символы. Примеры задания формата: "ГГГГММДДЧЧННСС", "ДД_ММ_ГГГГ_ЧЧ:НН:СС", "ССССС - тоже работает". 

Заключение.

 

В заключение хочется отметить, что хотя язык запросов платформы 1С:Предприятие имеет весьма слабые возможности работы со строками, использование техники искусственых таблиц отчасти компенсирует этот недостаток. С другой стороны, та же причина открывает широкий простор нашей изобретательности при написании запросов. Пользуйтесь этим!

Файлы

Наименование Файл Версия Размер Кол. Скачив.
Обработка для тестирования запросов
.erf 11,28Kb
22.01.13
75
.erf 11,28Kb 75 Скачать

См. также

Лучшие комментарии

1. Ёпрст (файл скачал) 24.01.2013 10:47
До чего только 1с-ина не доводит, всего лишь не реализовав простейший cast и convert в текстах запроса.
Сплошное извращение.
Ответили: (3) (28) (47)
# Ответить
11. ildarovich 25.01.2013 16:04
(6) Основой описанных преобразований является небанальная арифметика (то есть раздел математики, изучающий числа, их отношения и свойства). В школе такую «арифметику» проходят на информатике. Тема называется «системы счисления». В Вузе предмет, включающий эту тему, может называться «Арифметические и логические основы вычислительной техники».
Также хорошо бы уметь работать с матрицами и векторами. Тогда будут более понятны суммы произведений. В школьной программе матриц вроде бы нет (возможно, их изучают в математических классах). В Вузе матрицы встречаются во многих курсах, но раньше всего, наверное, в курсе «Линейная алгебра».
Не пропустите комбинаторику. Научитесь считать варианты. Не знаю, насколько часто этот раздел изучается отдельно, но он наверняка есть в «теории вероятностей», а это самый «практичный» (на мой взгляд) раздел математики. В рамках теории вероятностей можно познакомиться с необходимой частью теории множеств.
От теории множеств недалеко до реляционной алгебры – это основа табличных (реляционных) баз данных. Хотя, возможно, сама теория на каждый день не так уж и нужна.
Ну и еще одна смежная дисциплина – «теория графов». Это очень популярная абстрактная модель, на основе которой можно формулировать и решать многие практические задачи.
Ответили: (19)
# Ответить

Комментарии

1. Ёпрст (файл скачал) 24.01.2013 10:47
До чего только 1с-ина не доводит, всего лишь не реализовав простейший cast и convert в текстах запроса.
Сплошное извращение.
Ответили: (3) (28) (47)
# Ответить
2. Поручик 24.01.2013 11:46
(0) Почему-то мне нравятся твои работы. Что-то уже применял в рабочих проектах.
# Ответить
3. Поручик 24.01.2013 11:51
(1) Может вам ещё replace и insert с пивом подать?
Ответили: (5)
# Ответить
4. wunderland 24.01.2013 12:27
да, некоторых функций SQL иногда не хватает, и за такие вот статьи большой (+)
# Ответить
5. Ёпрст (файл скачал) 24.01.2013 12:44
(3) а что в этом плохого ?
Всё жлу, мот кто сподобится хотя бы под скуль написать вк для прямой записи в таблички с метапарсером и типизацией, как в клюшках. (вилдфайре не предлагать)
# Ответить
6. EfiopReal 25.01.2013 11:56
Может вопрос глупый, но все же. Не ткнете носом, что необходимо освежить в памяти из области математики, чтобы лучше понимать такие запросы?
Ответили: (7) (8) (10) (11)
# Ответить
7. andrewks 25.01.2013 13:34
(6) EfiopReal, из математики - почти ничего. ну, разве только матрицы и операции над ними
# Ответить
8. Hany 25.01.2013 13:39
(6) EfiopReal, дискретная математика, что-то из мат. анализа. Диф. ур. не надо.
Ответили: (9)
+ 1 [ Созинов; ]
# Ответить
9. andrewks 25.01.2013 13:42
(8) Hany, не расскажете поподробнее про мат.анализ?
# Ответить
11. ildarovich 25.01.2013 16:04
(6) Основой описанных преобразований является небанальная арифметика (то есть раздел математики, изучающий числа, их отношения и свойства). В школе такую «арифметику» проходят на информатике. Тема называется «системы счисления». В Вузе предмет, включающий эту тему, может называться «Арифметические и логические основы вычислительной техники».
Также хорошо бы уметь работать с матрицами и векторами. Тогда будут более понятны суммы произведений. В школьной программе матриц вроде бы нет (возможно, их изучают в математических классах). В Вузе матрицы встречаются во многих курсах, но раньше всего, наверное, в курсе «Линейная алгебра».
Не пропустите комбинаторику. Научитесь считать варианты. Не знаю, насколько часто этот раздел изучается отдельно, но он наверняка есть в «теории вероятностей», а это самый «практичный» (на мой взгляд) раздел математики. В рамках теории вероятностей можно познакомиться с необходимой частью теории множеств.
От теории множеств недалеко до реляционной алгебры – это основа табличных (реляционных) баз данных. Хотя, возможно, сама теория на каждый день не так уж и нужна.
Ну и еще одна смежная дисциплина – «теория графов». Это очень популярная абстрактная модель, на основе которой можно формулировать и решать многие практические задачи.
Ответили: (19)
# Ответить
12. bogdan_sukonnov 28.01.2013 10:49
в тексте описания примера упоминается строка "4957379257", а в примере разбирается 4957379252
Ответили: (13)
# Ответить
13. ildarovich 28.01.2013 10:57
(12) Спасибо! Вы очень внимательны. Поправлю поясняющий рисунок, когда буду обновлять статью.
# Ответить
14. bogdan_sukonnov 28.01.2013 14:11
тогда заодно поправьте подписи к колонкам в поясняющей таблице - насколько я понял, перепутаны местами А.П и А.С. Это, конечно, мелочи - статья замечательная, спасибо! Никак не могу понять как это работает, а самое главное, научиться самому писать такие запросы :(
+ 1 [ ildarovich; ]
# Ответить
15. bogdan_sukonnov 28.01.2013 14:19
интересно, что "1а2а3" преобразует к 10203 - как-то не очень хорошо
Ответили: (16)
# Ответить
16. ildarovich 28.01.2013 14:32
(15) Интерпретация ошибочных данных (здесь в запись числа вкрался не цифровой символ) требует до-определения правил преобразования. Их нетрудно внести в запрос, сделав это по примеру запроса №2. Реализованная интерпретация как кажется, имеет право на жизнь. Например, если столбик чисел Вы получили сканированием текста. Не распознанные цифры заменяются "0". В этом есть своя логика. Можно вообще отказываться от преобразования, обнаружив не цифровой символ. Но это уже детали.
# Ответить
17. bogdan_sukonnov 28.01.2013 14:45
наконец, осилил первый пример! Не стоит ли в целях облегчения понимания сделать отдельную таблицу "Б" с цифрами от 1 до 9? Плюс это поможет тем, кто будет преобразовывать строки длиной <10 (а я пытался переписать запрос на строку 3 символа - без отдельной таблицы "Б" никак). К тому же это, наверное, сократит количество комбинаций "А" и "Б", особенно для длинных строк "А". Ну и совсем было бы по 1С-овски дать осмысленные названия этим таблицам. Я понимаю, что программисты должны знать математику и т.д. Но почему бы не сделать людям понятнее?
Ответили: (18)
# Ответить
18. ildarovich 28.01.2013 15:21
(17) Отдельную таблицу заводить не хочется из эстетических соображений. Текст запроса в этом случае неминуемо станет длиннее. Предупредить о том, что таблица позиций и их весов должна иметь минимум ДЕСЯТЬ записей (таблица Б должна быть позволять пробегать и цифру "0"! Это важно), наверное, нужно . Проигрыш по времени из-за использования одной таблицы заключается в проверке ГДЕ, выполняемой ПЕРЕД соединением. Поэтому он НЕЗНАЧИТЕЛЕН. Над осмысленными именами таблиц я подумаю. Они нужны, согласен. С другой стороны, мне в другой публикации в качестве идеального решения приводили текст запроса для Postgre. Там имена таблиц и полей все состояли из одной латинской буквы и выглядело это действительно кратко и ясно. Так что тут одно из двух - либо математически коротко, чтобы запрос можно охватить одним взглядом, либо содержательные названия полей и таблиц.
# Ответить
19. EfiopReal 28.01.2013 18:22
(11) ildarovich, Спасибо большое, с первой половиной более менее могу разобраться, а вот вторую придется подтянуть.
# Ответить
20. akomar 29.01.2013 18:07
Но согласитесь запросы красиво смотрятся, пирамиды Хеопса)
# Ответить
21. Crush 30.01.2013 11:13
Замечательная статья! Спасибо большое!
Распечатал и добавил в избранное:)
# Ответить
22. It-developer 30.01.2013 16:41
Жесть. Сложно представить что это можно использовать. Типа сделать процедуру, а в нее передавать строковые числа? Не знаю, это может быть актуально для запроса, но передавать таблицу, а потом ее откуда-то получать не очень удобно
Ответили: (23)
# Ответить
23. ildarovich 30.01.2013 18:18
(22) Конечно,
это может быть актуально для запроса
. Вне запроса никаких проблем преобразования, конечно же, нет. Вас, видимо, смутил первый запрос в пакете. Он нужен ИСКЛЮЧИТЕЛЬНО ДЛЯ ТЕСТИРОВАНИЯ этих методов. Считается, что в реальных задачах строки, которые нужно преобразовать в числа или даты, берутся НЕПОСРЕДСТВЕННО из информационной базы. Возможно, нужно было подчеркнуть этот момент в самой статье.
# Ответить
24. ADirks 01.02.2013 10:37
Возможно, нужно было подчеркнуть этот момент в самой статье.

Если человек хотя бы примерно понимает, как это работает, то наверное поймёт и как использовать :)
# Ответить
25. ilov_boris 01.02.2013 15:40
Полезные сведения. Спасибо
# Ответить
26. alxbzm 06.02.2013 18:23
На Postgre 9 не работает к сожалению. Запрос падает с ошибкой function substr(...) does not exist. Именно на вычислении выражения ПОДТСТРОКА(...). Жаль, но сама идея запроса отличная.
Ответили: (31)
# Ответить
27. Andry.Boris 22.02.2013 02:39
Супер! Автор молоток
# Ответить
28. yuraos 28.03.2013 08:44
(1) Ёпрст,
много что не реализовали...
например хотя бы простейшие строковые функции
LTRIM() и RTRIM()
---
не будем грузить разработчиков платформы
функцией ALLTRIM()
которой почему-то в T-SQL у Микрософта нет.
Ответили: (29)
# Ответить
29. andrewks 28.03.2013 08:52
(28) yuraos, я думаю, разработчики платформы и так не слишком загрузились ))
Ответили: (30)
+ 2 [ AllexSoft; yuraos; ]
# Ответить
30. yuraos 28.03.2013 18:57
(29) andrewks,
ну думаю они даже очень загрузились в последнее время ...
...
только не тем, что нас простых смертых
(и довольно грешных) интересует.

Все в каких-то ОБЛАКАХ ВИТАЮТЬ !!!
:)
+ 1 [ tindir; ]
# Ответить
31. a-novoselov 04.06.2013 18:27
(26) Возможно у вас Postgre под 1С не патченый? Есть специальные сборки от EterSoft, в которых таких ошибок не возникает. Либо официальный патч от 1С (на официальном сайте выложен), но ни кто не дает гарантии что вы все правильно пропатчите... И патч, обычно, не для самых последних версий Postgre.
# Ответить
32. Al-X 20.06.2013 13:23
Спасибо за статью. Тоже недавно надо было в запросе преобразовывать строки в числа. Теперь буду знать, КАК ПРАВИЛЬНО ДЕЛАТЬ.
# Ответить
33. Synoecium 28.08.2013 11:11
Качественная подача материала, спасибо.
# Ответить
34. solarlion 11.09.2013 11:40
Отличная идея. У меня как раз возникла задача, где придется реализовать 1 вариант.
# Ответить
36. ronhard 20.01.2014 16:55
Есть все-таки на свете умные люди.
Это, конечно, мелочи - статья замечательная, спасибо! Никак не могу понять как это работает, а самое главное, научиться самому писать такие запросы :(

Поддерживаю на 100%
# Ответить
37. yura1960 13.06.2014 19:12
Хм... С этой стороны я не догадался рассматривать эту проблему. Хотя у меня функции короче и проще, но кое в чем они проигрывают.
Автору спасибо. Попробую поизвращаться. Если реально поможет, то будет огромный СЕНКС!!!
# Ответить
38. Lama12-1 09.07.2014 13:55
А по какому национальному стандарту происходит преобразование?
Ответили: (39)
# Ответить
39. ildarovich 09.07.2014 17:30
(38) Lama12-1, если речь о "национальном стандарте", то, видимо, имеется ввиду преобразование строка -> дата.
Это преобразование задается ФОРМАТНОЙ СТРОКОЙ, которую в примере 6 можно задавать.
В примерах 4 и 5 форматная строка фиксирована. Она имеет вид ГГГГММДД. Например, сегодняшняя дата в этом формате "20140709".
Если вы чуть-чуть разбираетесь в запросах, то сможете составить преобразование под любой формат даты, ну или под тот национальный стандарт, который нужен.
Ответили: (47)
# Ответить
40. chmv 07.08.2014 08:37
На самом деле это большая проблема.
До сих пор не могу написать
Выбрать Сотрудник.Наименование+Сотрдуник.ДатаРождения как СотрудникСДатойРождения
Подскажите как это сделать?
Ответили: (41)
# Ответить
41. ildarovich 07.08.2014 09:12
(40) chmv, то, что вы хотите, требует преобразования из даты в строку, а в данной статье рассматривается обратное преобразование - из строки в дату. Так, что приемы, описанные в данной статье, напрямую вам не помогут.
# Ответить
42. luic 17.08.2014 09:42
Спасибо, очень помогло))
# Ответить
43. evillit 22.10.2014 19:56
Полезная статья. В мемориз.
# Ответить
44. chmv 01.12.2014 10:40
Спасибо. А попроще нельзя?
Ответили: (45)
# Ответить
45. ildarovich 01.12.2014 13:47
(44) chmv, попроще пока не получилось
# Ответить
46. SemenovaMarinaV 27.01.2015 14:00
жаль что 1с это не предусмотрела, а то приходится извращаться
# Ответить
47. pavlinuh 29.01.2015 16:36
(1)(1)(39) ildarovich, В учебниках "Алгебра и начала анализа" конца 80-х - начала 90-х для 10/11 классов этот раздел назывался "комбинаторика". В современных учебных пособиях, в зависимости от издания/автора, он называется "введение в теорию вероятности", "теория вероятности", "логические задачи" и т.п.
Что там в институтах - не в курсе.
# Ответить
48. adva 08.06.2015 08:58
Иногда для практических целей нужно наоборот получить в запросе вместо числа строку. Имеется ли такое же красивое решение?
Ответили: (49)
# Ответить
49. ildarovich 08.06.2015 09:48
(48) adva, такое решение имеется. Оно описано в статье Выразить число как строку и дату как строку в запросе .
Ответили: (50)
+ 1 [ adva; ]
# Ответить
50. adva 08.06.2015 12:38
(49) спасибо, не попадалось ранее, а еще может быть есть статья о том, как пронумеровать в запросе строки (иногда нет номеров строк, а очень хочется, чтобы дальше в запросе использовать, не выгружая в ТЗ)?
Ответили: (51)
# Ответить
51. ildarovich 08.06.2015 13:34
(50) adva, это слишком простая задача для статьи. Вот в задаче 14 из статьи Минимализмы для нумерации таблицы дат используется подзапрос
ВЫБРАТЬ 
    Даты.Дата, 
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ДатыДо.Дата) КАК Номер 
ПОМЕСТИТЬ НомераДат 
ИЗ 
    ВТДаты КАК Даты 
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДаты КАК ДатыДо 
        ПО (ДатыДо.Дата < = Даты.Дата) 
СГРУППИРОВАТЬ ПО 
    Даты.Дата 
...Показать Скрыть

Аналогично может быть пронумерована любая другая таблица, в которой есть поле, определяющее порядок строк для нумерации. Если такого поля (набора полей) нет, то задача в запросе не может быть решена. Это принципиальный момент.
Соединение таблицы с собой довольно затратная по времени операция. В некоторых случаях нумерацию можно ускорить за счет того, что нумерация - это тот же нарастающий итог и его можно ускорить как показано в статье Баттерфляй - метод быстрого расчета нарастающего итога в запросе. Но это имеет смысл, только если строк больше 2000 (для SQL).
+ 1 [ adva; ]
# Ответить
Внимание! За постинг в данном форуме $m не начисляются.
Внимание! Для написания сообщения необходимо авторизоваться
Текст сообщения*
Прикрепить файл






IE 2016