Запрос: товары с уникальной ценой
Условие
Дана таблица из двух колонок: Товар и Цена. Нужно выбрать товары, у которых цена уникальна (встречается ровно один раз).
Реализуйте решение несколькими способами (минимум два варианта запроса).
Пример
Входные данные:
| Товар | Цена |
|---|---|
| А | 100 |
| Б | 200 |
| В | 100 |
| Г | 300 |
Выход: Б (цена 200), Г (цена 300)
Товары А и В имеют одинаковую цену 100, поэтому не включаются в результат.
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Решение
Обзор задачи
Эта задача требует определения товаров с уникальными ценами — то есть цены, которые встречаются только один раз в таблице. Это тест на понимание:
- GROUP BY и агрегирующих функций (COUNT)
- HAVING условий
- Различных подходов к решению одной задачи
- Оптимизации запросов
Способ 1: С использованием GROUP BY и HAVING с COUNT
Выбрать
Товар.Ссылка,
Товар.Наименование Как Товар,
ЦенаТовара.Цена
Из
Справочник.Товар Как Товар
Внутреннее Соединение РегистрСведений.ЦенаТовара Как ЦенаТовара
На Товар.Ссылка = ЦенаТовара.Товар
Группировать По
Товар.Ссылка,
Товар.Наименование,
ЦенаТовара.Цена
Имеющие
КОЛИЧЕСТВО(*) = 1
Упорядочить По
Товар.Наименование
Описание: Группируем по товару и цене, затем отбираем только те группы, где количество совпадений = 1.
Способ 2: С подзапросом для подсчёта ценовых дубликатов
Выбрать
Т.Ссылка,
Т.Наименование Как Товар,
Ц.Цена
Из
Справочник.Товар Как Т
Внутреннее Соединение РегистрСведений.ЦенаТовара Как Ц
На Т.Ссылка = Ц.Товар
Где
(Выбрать КОЛИЧЕСТВО(*)
Из РегистрСведений.ЦенаТовара Как ЦеныВнут
Где ЦеныВнут.Цена = Ц.Цена) = 1
Упорядочить По
Т.Наименование
Описание: Для каждого товара в подзапросе считаем, сколько раз встречается его цена во всей таблице. Отбираем товары, где это значение = 1.
Способ 3: Через виртуальную таблицу с промежуточным подсчётом
Выбрать
Товар.Ссылка,
Товар.Наименование,
Цены.Цена
Из
(
Выбрать
ЦенаТовара.Товар,
ЦенаТовара.Цена,
КОЛИЧЕСТВО(*) Как КоличествоТоваров
Из
РегистрСведений.ЦенаТовара Как ЦенаТовара
Группировать По
ЦенаТовара.Цена
) Как СтатистикаЦен
Внутреннее Соединение РегистрСведений.ЦенаТовара Как Цены
На СтатистикаЦен.Цена = Цены.Цена
Внутреннее Соединение Справочник.Товар Как Товар
На Цены.Товар = Товар.Ссылка
Где
СтатистикаЦен.КоличествоТоваров = 1
Упорядочить По
Товар.Наименование
Описание: Создаём виртуальную таблицу со статистикой по ценам, затем присоединяем её к основной таблице.
Способ 4: С использованием РАЗЛИЧНЫЕ и дополнительного отбора
Выбрать Различные
Т.Ссылка,
Т.Наименование,
ЦеныГруп.Цена
Из
(
Выбрать
ЦенаТовара.Цена,
КОЛИЧЕСТВО(*) Как КолТоваров
Из
РегистрСведений.ЦенаТовара Как ЦенаТовара
Группировать По
ЦенаТовара.Цена
Имеющие
КОЛИЧЕСТВО(*) = 1
) Как ЦеныГруп
Внутреннее Соединение РегистрСведений.ЦенаТовара Как Цены
На ЦеныГруп.Цена = Цены.Цена
Внутреннее Соединение Справочник.Товар Как Т
На Цены.Товар = Т.Ссылка
Упорядочить По
Т.Наименование
Описание: Находим уникальные цены в подзапросе (HAVING COUNT = 1), затем присоединяем товары с этими ценами.
Способ 5: Использование оконных функций (если поддерживается версия 1С)
Выбрать
Товар.Ссылка,
Товар.Наименование,
Цены.Цена
Из
Справочник.Товар Как Товар
Внутреннее Соединение
(
Выбрать
Товар,
Цена,
КОЛИЧЕСТВО(*) Над (Раздел Все Упорядочить По Цена) Как КолценыВсего,
КОЛИЧЕСТВО(*) Над (Раздел По Цена) Как КолценыВГруппе
Из
РегистрСведений.ЦенаТовара
) Как ЦенаТовара
На Товар.Ссылка = ЦенаТовара.Товар
Где
ЦенаТовара.КолценыВГруппе = 1
Упорядочить По
Товар.Наименование
Способ 6: Через антисоединение (NOT IN)
Выбрать
Товар.Ссылка,
Товар.Наименование Как Товар,
Цена.Цена
Из
Справочник.Товар Как Товар
Внутреннее Соединение РегистрСведений.ЦенаТовара Как Цена
На Товар.Ссылка = Цена.Товар
Где
Цена.Цена Не В
(
Выбрать
ЦЦена.Цена
Из
РегистрСведений.ЦенаТовара Как ЦЦена
Группировать По
ЦЦена.Цена
Имеющие
КОЛИЧЕСТВО(*) > 1
)
Упорядочить По
Товар.Наименование
Описание: Находим все цены, которые встречаются более одного раза, затем исключаем товары с этими ценами.
Рекомендуемые варианты
Для простоты и читаемости — Способ 1:
Выбрать
Товар.Ссылка,
Товар.Наименование Как Товар,
ЦенаТовара.Цена
Из
Справочник.Товар Как Товар
Внутреннее Соединение РегистрСведений.ЦенаТовара Как ЦенаТовара
На Товар.Ссылка = ЦенаТовара.Товар
Группировать По
Товар.Ссылка,
Товар.Наименование,
ЦенаТовара.Цена
Имеющие
КОЛИЧЕСТВО(*) = 1
Упорядочить По
Товар.Наименование
Для гибкости и отладки — Способ 2:
Выбрать
Т.Ссылка,
Т.Наименование Как Товар,
Ц.Цена
Из
Справочник.Товар Как Т
Внутреннее Соединение РегистрСведений.ЦенаТовара Как Ц
На Т.Ссылка = Ц.Товар
Где
(Выбрать КОЛИЧЕСТВО(*)
Из РегистрСведений.ЦенаТовара Как ЦеныВнут
Где ЦеныВнут.Цена = Ц.Цена) = 1
Упорядочить По
Т.Наименование
Реализация в коде 1С
Процедура НайтиТоварыСУникальнымиЦенами()
ТекстЗапроса = "Выбрать
| Товар.Ссылка,
| Товар.Наименование Как Товар,
| ЦенаТовара.Цена
|Из
| Справочник.Товар Как Товар
| Внутреннее Соединение РегистрСведений.ЦенаТовара Как ЦенаТовара
| На Товар.Ссылка = ЦенаТовара.Товар
|Группировать По
| Товар.Ссылка,
| Товар.Наименование,
| ЦенаТовара.Цена
|Имеющие
| КОЛИЧЕСТВО(*) = 1
|Упорядочить По
| Товар.Наименование";
Запрос = Новый Запрос(ТекстЗапроса);
РезультатЗапроса = Запрос.Выполнить();
ТаблицаРезультата = РезультатЗапроса.Выгрузить();
Для каждого Строка Из ТаблицаРезультата Цикл
Сообщить("Товар: " + Строка.Товар + ", Цена: " + Строка.Цена);
КонецЦикла;
КонецПроцедуры
Тестирование на примере
Для входных данных:
А - 100
Б - 200
В - 100
Г - 300
Ожидаемый результат:
Б - 200 (цена встречается 1 раз)
Г - 300 (цена встречается 1 раз)
Цены, которые НЕ попадут в результат:
- 100 (встречается 2 раза: у товара А и В)
Сравнение подходов
| Способ | Сложность | Читаемость | Производительность | Когда использовать |
|---|---|---|---|---|
| 1 | Простой | Хорошая | Хорошая | Production код, простые случаи |
| 2 | Средний | Хорошая | Средняя | Отладка, небольшие таблицы |
| 3 | Сложный | Средняя | Хорошая | Большие объёмы данных |
| 4 | Средний | Средняя | Хорошая | Когда нужна промежуточная статистика |
| 5 | Сложный | Хорошая | Отличная | Большие таблицы (если версия поддерживает) |
| 6 | Средний | Хорошая | Средняя | Когда удобнее искать "исключения" |
Ключевые моменты
- GROUP BY + HAVING — основной паттерн для работы с группировками
- КОЛИЧЕСТВО(*) — подсчитывает количество строк в группе
- Подзапросы — позволяют использовать текущие значения во WHERE
- Внутреннее Соединение — гарантирует только товары с ценами
- Упорядочить По — для удобства просмотра результатов