Написать запрос

1. cdpomaa 5 22.07.24 16:42 Сейчас в теме
Компания продает кабель.

Кабель продается в бобинах по 28 и 67 метров. Не режутся.

На складе лежит какое-то произвольное количество этих бобин обоих видов.

Клиент может попросить любую длину.



Нужно одним запросом подобрать оптимальное количество бобин одной и второй длин с учетом наличия на складе.
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
12. Anton_new01 22.07.24 17:21 Сейчас в теме +0.92 $m
логика:
1. получаем Остаток28 и Остаток67
2. берем целую часть от ТребуетсяХ/67 и сравниваем с остатком67 берем минимум из двух чисел - это количество 67бабин
3 (ТребуетсяХ - количество67бабин * 67)/28 округление вверх и сравниваем с остатком28 - берем минимум из двух чисел это количество 28 бабин

делать эту логику в запросе... ну такое себе.

"ВЫБРАТЬ
|	ТоварыНаСкладахОстатки.Товар КАК Товар
|	Поместить втОстатокБабина28
|ИЗ
|	РегистрНакопления.ТоварыНаСкладах.Остатки(, , , Товар = &Бабина28) КАК ТоварыНаСкладахОстатки
|	;
|ВЫБРАТЬ
|	ТоварыНаСкладахОстатки.Товар КАК Товар
|	Поместить втОстатокБабина67
|ИЗ
|	РегистрНакопления.ТоварыНаСкладах.Остатки(, , , Товар = &Бабина67) КАК ТоварыНаСкладахОстатки
|	;
|ВЫБРАТЬ
|	Выбор
|		Когда ЦЕЛ(&ТребуетсяХ/67) > втОстатокБабина67.Товар Тогда  втОстатокБабина67.Товар
|		Иначе ЦЕЛ(&ТребуетсяХ/67) 
|			Конец Как Количество67бабин
|	Поместить втКоличество67бабин
|ИЗ
|	втОстатокБабина67 КАК втОстатокБабина67
|	;
|ВЫБРАТЬ
|	Выбор
|		Когда ЦЕЛ((&ТребуетсяХ - втКоличество67бабин.Количество67бабин*67)/28)+1 > втОстатокБабина28.Товар Тогда  втОстатокБабина28.Товар
|		Иначе ЦЕЛ((&ТребуетсяХ - втКоличество67бабин.Количество67бабин*67)/28)+1 
|			Конец Как Количество28бабин
|	Поместить втКоличество28бабин
|ИЗ
|  втКоличество67бабин как втКоличество67бабин,
|	втОстатокБабина28 КАК втОстатокБабина28,
|	;
|ВЫБРАТЬ
|	втКоличество67бабин.втКоличество67бабин,
|	втКоличество28бабин.втКоличество28бабин
|ИЗ
|  втКоличество67бабин как втКоличество67бабин,
|	втКоличество28бабин КАК втКоличество28бабин"
Показать


PS. небольшая не точность в Количество28бабин - так как нет функции окрулить вверх я использовал взять цел и +1 - это не всегда равно окрулению вверх, если у нас число кратно 28.
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Lenten 25 22.07.24 16:51 Сейчас в теме
ровно надо? или есть + - ?
3. cdpomaa 5 22.07.24 16:51 Сейчас в теме
если нужно например 29 метров то 2 бобины по 28
4. cdpomaa 5 22.07.24 16:52 Сейчас в теме
если 68 метров то 1 бобина на 67 и 1 на 28
10. VmvLer 22.07.24 17:15 Сейчас в теме
(4)
если 68 метров то 1 бобина на 67 и 1 на 28


будет
67+28 = 95

хотя по условию:
Нужно одним запросом подобрать оптимальное количество бобин одной и второй длин с учетом наличия на складе

28+28+28 = 84 (при наличии)

оптимальным, как я пониманию минимальной общей длиной, будет 28*3.

Уточните, что значит "оптимальное количество бобин".
По количеству бобин, по минимальной общей длине, ...?
5. usershmuser 22.07.24 16:54 Сейчас в теме
Предлагаю задачу разложить на запрос и обработку запроса, т.е. сначала делаем запрос остатков, а уже потом обрабатываем логикой
6. cdpomaa 5 22.07.24 16:55 Сейчас в теме
нужно запросом одним получить нужное количество бобин
7. cdpomaa 5 22.07.24 16:56 Сейчас в теме
Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ТЗ.Количество28 КАК Количество28,
		|	ТЗ.Количество67 КАК Количество67
		|ПОМЕСТИТЬ ОстаткиНаСкладе
		|ИЗ
		|	&ТЗ КАК ТЗ";
	
	Запрос.УстановитьПараметр("ТЗ",ТЗ);
Показать
8. usershmuser 22.07.24 17:04 Сейчас в теме
могу написать логику, целиком запрос писать лень)))
9. cdpomaa 5 22.07.24 17:05 Сейчас в теме
ок, я перепишу под запрос
13. usershmuser 22.07.24 17:27 Сейчас в теме
(9)
1. Делаем запрос на остатки
2. Устанавливаем параметр - НеобходимоеКоличество
3. Логика:
СколькоНужно28 = НеобходимоеКоличество / 28;
СколькоНужно67 = НеобходимоеКоличество / 67;
Если (СколькоНужно67 < 1) И (СколькоНужно28 < 1) Тогда
Ответ = Количество28 * 1;
Иначе Если (СколькоНужно67 < 1) И (СколькоНужно28 > 1) Тогда
Ответ = Количество67 * 1;

И методами сравнения далее определяем, честно сказать, не знаю как в запросе можно обрабатывать числа т.к. в основном нам будут интересны числа после запятой.
11. soft_wind 22.07.24 17:17 Сейчас в теме
может быть перебор всех вариантов бобин с расчетом остатка
и выбор варианта с минимальным остатком

готовим две таблицы с бобинами 1 и 2, помещаем во времТаб
бобина, Количество (при формировании этих таблиц как раз и ограничиваем их остатками)
б1, 0
б1, 1
б1, 2
б1, 3
б1, 4 и тд



и
б2, 0
б2, 1

б2, 2
б2, 3
б2, 4 и тд

соединяем эти две таблицы через запятую, получаем всевозможные варианты сочетаний бодин
и рассчитываем общую длину в каждой строке
затем отбираем строчки где общая длинна чуть больше требуемой,
(так как операции умножения и сложения самые простые, результат будет почти мгновенный)
12. Anton_new01 22.07.24 17:21 Сейчас в теме +0.92 $m
логика:
1. получаем Остаток28 и Остаток67
2. берем целую часть от ТребуетсяХ/67 и сравниваем с остатком67 берем минимум из двух чисел - это количество 67бабин
3 (ТребуетсяХ - количество67бабин * 67)/28 округление вверх и сравниваем с остатком28 - берем минимум из двух чисел это количество 28 бабин

делать эту логику в запросе... ну такое себе.

"ВЫБРАТЬ
|	ТоварыНаСкладахОстатки.Товар КАК Товар
|	Поместить втОстатокБабина28
|ИЗ
|	РегистрНакопления.ТоварыНаСкладах.Остатки(, , , Товар = &Бабина28) КАК ТоварыНаСкладахОстатки
|	;
|ВЫБРАТЬ
|	ТоварыНаСкладахОстатки.Товар КАК Товар
|	Поместить втОстатокБабина67
|ИЗ
|	РегистрНакопления.ТоварыНаСкладах.Остатки(, , , Товар = &Бабина67) КАК ТоварыНаСкладахОстатки
|	;
|ВЫБРАТЬ
|	Выбор
|		Когда ЦЕЛ(&ТребуетсяХ/67) > втОстатокБабина67.Товар Тогда  втОстатокБабина67.Товар
|		Иначе ЦЕЛ(&ТребуетсяХ/67) 
|			Конец Как Количество67бабин
|	Поместить втКоличество67бабин
|ИЗ
|	втОстатокБабина67 КАК втОстатокБабина67
|	;
|ВЫБРАТЬ
|	Выбор
|		Когда ЦЕЛ((&ТребуетсяХ - втКоличество67бабин.Количество67бабин*67)/28)+1 > втОстатокБабина28.Товар Тогда  втОстатокБабина28.Товар
|		Иначе ЦЕЛ((&ТребуетсяХ - втКоличество67бабин.Количество67бабин*67)/28)+1 
|			Конец Как Количество28бабин
|	Поместить втКоличество28бабин
|ИЗ
|  втКоличество67бабин как втКоличество67бабин,
|	втОстатокБабина28 КАК втОстатокБабина28,
|	;
|ВЫБРАТЬ
|	втКоличество67бабин.втКоличество67бабин,
|	втКоличество28бабин.втКоличество28бабин
|ИЗ
|  втКоличество67бабин как втКоличество67бабин,
|	втКоличество28бабин КАК втКоличество28бабин"
Показать


PS. небольшая не точность в Количество28бабин - так как нет функции окрулить вверх я использовал взять цел и +1 - это не всегда равно окрулению вверх, если у нас число кратно 28.
20. cdpomaa 5 22.07.24 19:10 Сейчас в теме
(12) и сравниваем с остатком28 - берем минимум
Мин(Цел(НеобходимоеКоличество / 67),ОстатокНаСкладе67) ???
23. Anton_new01 23.07.24 08:15 Сейчас в теме
(20)
это в коде такое возможно.
тока если речь про остаток28, то так: МИН(Цел(НеобходимоеКоличество/28), остатокНаСкладе28)

в запросе так низя.

смысл в том,чтобы не взять больше чем остаток на складе..

PS. благодарю за $m
25. cdpomaa 5 24.07.24 19:34 Сейчас в теме
(23)
Если нужно 132м то не правильно считает 1 по 67 и 3 по 28
А нужно 2 по 67
27. Anton_new01 25.07.24 09:52 Сейчас в теме
(25) т.е. критерий правильно/ не правильно - это минимум выражения количество67*67+количество28*28 ?
сейчас подумаю какой алгоритм составить, для такого результата.
29. cdpomaa 5 25.07.24 12:14 Сейчас в теме
(27) нужно оптимальное количество бобин, тоесть если 132 м надо то 132/67 будет 1,97
Значит 2 бобины по 67 будет оптимально чем 1 по 67 и 3 по 28
31. Anton_new01 25.07.24 13:06 Сейчас в теме
(25)
алгоритм:
1. подготавливаем таблицу нумерации от 0 до 99.
2. считаем все возможные варианты количества 67 бабин
от 0 до максимум Кол67 = Мин( ЦЕЛ(&НеобходимоеКоличество / 67) + 1, Остаток67)

3. к каждому варианту количества 67 бабин считаем количество 28 бабин по формуле
Кол28=Мин(ОкруглВверх((ТребуетсяХ - Кол67)/28), Остаток28)
4. находим минимум кол67*67+кол28*28

PS. ограничение метода в количестве предварительной таблицы в 67*100=6700 метров т.к. у нас сотня вариантов заложена нумератором. Можно заложить больше, но в любом случае будет некое ограничение.


ВЫБРАТЬ
0 КАК Номер
ПОМЕСТИТЬ втПятерка

ОБЪЕДИНИТЬ

ВЫБРАТЬ
1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
4
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
АВТОНОМЕРЗАПИСИ() КАК Номер,
Пятерка1.Номер КАК НомерП
ПОМЕСТИТЬ втСотня
ИЗ
втПятерка КАК Пятерка1,
втПятерка КАК Пятерка2,
втПятерка КАК Пятерка3
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
ТЗ.Количество28 КАК Кол28,
ТЗ.Количество67 КАК Кол67
ПОМЕСТИТЬ втОстатки
ИЗ
&ТЗ КАК ТЗ
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
ВЫБОР
КОГДА ЦЕЛ(&НеобходимоеКоличество / 67) + 1 >= втОстатки.Кол67
ТОГДА втОстатки.Кол67
ИНАЧЕ ЦЕЛ(&НеобходимоеКоличество / 67) + 1
КОНЕЦ КАК МаксКол67
ПОМЕСТИТЬ втОстатки67
ИЗ
втОстатки КАК втОстатки
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
втСотня.Номер - 1 КАК Кол67,
ВЫБОР
КОГДА (&НеобходимоеКоличество - (втСотня.Номер + 1) * 67) / 28 > Остатки.Кол28
ТОГДА Остатки.Кол28
ИНАЧЕ (ВЫРАЗИТЬ((&НеобходимоеКоличество - (втСотня.Номер + 1) * 67) / 28 - 0.5 КАК ЧИСЛО(15, 0))) + 1
КОНЕЦ КАК Кол28
ПОМЕСТИТЬ втВсеВариантыБабин
ИЗ
втСотня КАК втСотня,
втОстатки67 КАК втОстатки67,
втОстатки КАК Остатки
ГДЕ
втСотня.Номер - 1 >= втОстатки67.МаксКол67
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ ПЕРВЫЕ 5
ВсеВариантыБабин.Кол67 КАК Кол67,
ВсеВариантыБабин.Кол28 КАК Кол28,
ВсеВариантыБабин.Кол67 * 67 + ВсеВариантыБабин.Кол28 * 28 КАК Сортировка
ИЗ
втВсеВариантыБабин КАК ВсеВариантыБабин

УПОРЯДОЧИТЬ ПО
Сортировка
32. cdpomaa 5 25.07.24 14:17 Сейчас в теме
(31) При 132 выдает -91 и 38
Прикрепленные файлы:
ВнешняяОбработка1.epf
33. Anton_new01 25.07.24 15:09 Сейчас в теме
(32)
со знаками накосячил.
поправил условия прикрепил обработку
Прикрепленные файлы:
ВОКоличествоБАбин_01.epf
14. yispepotri 22.07.24 17:30 Сейчас в теме
внесу свой гов.. запрос, 35 и 280 это значение в метрах, которое будет передаваться в качестве параметра. Не продумал до конца логику, вдруг немного поможет)

ВЫБРАТЬ
     ВЫБОР
        КОГДА 35 > 28
        ТОГДА
        	ВЫБОР КОГДА ЦЕЛ(35 / 28) = 35 ТОГДА ЦЕЛ(35 / 28) 
        	КОГДА ЦЕЛ(35 / 28) > 28ТОГДА ЦЕЛ(35 / 28) + 1 
        	ИНАЧЕ 0
        	КОНЕЦ
        КОГДА 35 = 28 
        ТОГДА     
        	1  	
        ИНАЧЕ 
        	0
        КОНЕЦ КАК Количество28

    ,ВЫБОР
        КОГДА 280 >= 67
        ТОГДА
            ЦЕЛ(280 / 67) 
     ИНАЧЕ
            0
     КОНЕЦ КАК Количество67
Показать
15. soft_wind 22.07.24 17:39 Сейчас в теме
(11) если сами не осилите такой запрос, пишите
(очень оригинальненькая и интересная задачка)
16. Lenten 25 22.07.24 17:41 Сейчас в теме
вот решение для произвольных чисел.

Соответственно в вашем варианте ячейки это конкретные бабины. Сколько ячеек столько и бабин

http://fixin.com.ru/articles/alg_makesumm/article.htm
17. Fox-trot 163 22.07.24 18:26 Сейчас в теме
18. Lenten 25 22.07.24 18:28 Сейчас в теме
(17) не думал что это принципиально
19. Fox-trot 163 22.07.24 18:51 Сейчас в теме
(18) согласен, но не нам же решать
таковы условия задачи
такие дела
21. cdpomaa 5 22.07.24 19:27 Сейчас в теме
Количество67 = Цел(НеобходимоеКоличество / 67);
	Количество28 = ОкрБольш((НеобходимоеКоличество-Количество67*67)/28);
	
	Если ОстатокНаСкладе28 - Количество28 < 0 Тогда
		Сообщить("Не хватает 28 м. бабин в количестве: " + Строка(Количество28 - ОстатокНаСкладе28) + " шт.")
	КонецЕсли;
	
	Если ОстатокНаСкладе67 - Количество67 < 0 Тогда
		Сообщить("Не хватает 67 м. бабин в количестве: " + Строка(Количество67 - ОстатокНаСкладе67) + " шт.")
	КонецЕсли;
		

	
Функция ОкрБольш(Ч, Разрядность=0) Экспорт
    Возврат Окр(Ч+Pow(10, Разрядность)/2, Разрядность, РежимОкругления.Окр15как10);
КонецФункции
Показать
22. cdpomaa 5 22.07.24 20:46 Сейчас в теме
ВЫБРАТЬ
	ТЗ.Количество28 КАК Количество28,
	ТЗ.Количество67 КАК Количество67
ПОМЕСТИТЬ ОстаткиНаСкладе
ИЗ
	&ТЗ КАК ТЗ
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВЫБОР
		КОГДА ЦЕЛ(&НеобходимоеКоличество / 67) > ОстаткиНаСкладе.Количество67
			ТОГДА ОстаткиНаСкладе.Количество67
		ИНАЧЕ ЦЕЛ(&НеобходимоеКоличество / 67)
	КОНЕЦ КАК Количество67,
	ВЫБОР
		КОГДА (&НеобходимоеКоличество - ЦЕЛ(&НеобходимоеКоличество / 67) * 67) / 28 > ОстаткиНаСкладе.Количество28
			ТОГДА ОстаткиНаСкладе.Количество28
		ИНАЧЕ (ВЫРАЗИТЬ((&НеобходимоеКоличество - ЦЕЛ(&НеобходимоеКоличество / 67) * 67) / 28 - 0.5 КАК ЧИСЛО(15, 0))) + 1
	КОНЕЦ КАК Количество28
ИЗ
	ОстаткиНаСкладе КАК ОстаткиНаСкладе
Показать
Anton_new01; +1 Ответить
24. soft_wind 23.07.24 11:30 Сейчас в теме
кому интересно, попробуйте такой вариант

//таб с номерами > мак остатка (для примера взято 10)
Выбрать 0 как Номер поместить втНомера
объединить все Выбрать 1
объединить все Выбрать 2
объединить все Выбрать 3
объединить все Выбрать 4
объединить все Выбрать 5
объединить все Выбрать 6
объединить все Выбрать 7
объединить все Выбрать 8
объединить все Выбрать 9
объединить все Выбрать 10
;                                                 
//эмуляция запроса остатков по бобинам
Выбрать "Б28" как товар, 9 как Количество поместить втОстатки
объединить все Выбрать "Б67", 8
; 
//две таблицы с товарами для расчета
Выбрать
	втОстатки.Товар,
	втНомера.Номер как Количество,
	28 как длина
поместить втТаб1	
из
	втОстатки
левое соединение втНомера
по втОстатки.Количество >= втНомера.Номер
где
	втОстатки.Товар = "Б28"
;
Выбрать
	втОстатки.Товар,
	втНомера.Номер как Количество,
	67 как длина
поместить втТаб2	
из
	втОстатки
левое соединение втНомера
по втОстатки.Количество >= втНомера.Номер
где
	втОстатки.Товар = "Б67"
;
Выбрать первые 1 //3
	т1.Товар,
	т1.Количество,
	т2.Товар,	
	т2.Количество,
	т1.Количество * т1.Длина + т2.Количество * т2.Длина  как Длина 
из
	втТаб1 т1, втТаб2 т2
где
	т1.Количество * т1.Длина + т2.Количество * т2.Длина >= &НужнаяДлина
Упорядочить по
5

Показать
26. Said-We 25.07.24 01:42 Сейчас в теме
(1) Скучно....
Усложнил задачу из спортивного интереса.
Бобины могут быть любой длины, а не только 67 и 28. У каждой бобины есть место хранения и дата производства.
Необходимо подобрать либо заданное количество метража, а если подобрать не удаётся то ближайшее большее. При этом необходимо стараться подбирать бобины с максимальной длиной в первую очередь и среди прочих равных брать с более ранней датой производства. Если среди двух одинаковых бобин дата производства одинаковая, то первую попавшуюся. Не важно какую из этих двух.
Если метража на складе не достаточно, то в результате должны быть все имеющиеся.
Результат: метраж бобины через запятую, места хранения через запятую, общий метраж (sum_kol).
Для понимания алгоритма вывел ещё и служебную не обязательную колонку (sum_npp).

https://onecompiler.com/postgresql/42m5hvdy6

Запрос на PsgSQL. В начале задается количество в
vt_const as (SELECT 1000 as a)
Вместо 1000 можно рисовать любые положительные циферки. Это тот метраж, который запросил клиент.
Прикрепленные файлы:
28. Said-We 25.07.24 10:32 Сейчас в теме
Проверял кто результат в запросе {26}?
Для 129 и 132 будут результаты 129 и 133 (на скринах).

Такой же по сути запрос отработал и на SQLite и на MS SQL.
Только в 1С, к огромному сожалению, нет рекурсивных запросов и обычной функции нумерации (только подобие, реализованное странным образом).
Прикрепленные файлы:
30. Said-We 25.07.24 12:33 Сейчас в теме
(29) вариант в {10} для значения 84. Там вообще резать ничего не нужно, но и 67 брать не нужно.
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот