Запрос, выбрать первую запись из нескольких групп одного запроса

1. nikivr 07.03.17 20:12 Сейчас в теме
Добрый день, уважаемые коллеги!

Подскажите пожалуйста, каким образом можно отобрать первую запись из нескольких групп записей.

Например:

Поле1 Поле2 Поле3
Знач1 Вася Сауна
Знач2 Петя Дом
Знач2 Сережа Дом
Знач2 Андрей Дом
Знач3 Иван Бильярд
Знач3 Веня Бильярд

А на выходе должно получиться:

Знач1 Вася Сауна
Знач2 Петя Дом
Знач3 Иван Бильярд

Это нужно сделать одним запросом, а не обходом по группировкам
По теме из базы знаний
Ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
3. ipetrochenko 85 08.03.17 00:05 Сейчас в теме
(1) А сортировка какая должна быть? По какому принципу должна браться первая запись в группе?
4. nikivr 08.03.17 10:50 Сейчас в теме
(3) Принципов несколько, если не выполняется одно условие проверяется другое. Мне удалось при помощи упорядочивания сделать строки первыми. Но видимо кроме нумерации других вариантов нет
6. SP17081992 5 08.03.17 11:02 Сейчас в теме
(4) Зависимо от условии сортировки можно добавить еще одну колонку типа булево, а потом фильтровать по этому колонку. Вроде так:
Поле1 Поле2 Поле3 Поле4
Знач1 Вася Сауна Истина
Знач2 Петя Дом Истина
Знач2 Сережа Дом Ложь
Знач2 Андрей Дом Ложь
Знач3 Иван Бильярд Истина
Знач3 Веня Бильярд Ложь

после фильтра где Поле4 = Истина, будет необходимый результат.

13. nikivr 09.03.17 09:58 Сейчас в теме
(6) Условий несколько и они числовые, проверять каждую колонку на максимум?
26. SP17081992 5 09.03.17 14:49 Сейчас в теме
(13) Если условия числовые и нужно максимальние можно решать вашу задачу с помощью:
ИМЕЮЩИЕ МАКСИМУМ()
29. nikivr 10.03.17 09:51 Сейчас в теме
(26) Полей несколько и условий тоже. Если числа в двух строках совпадут то проверяется следующее. А если в конце остается несколько строк, то и берем любое
8. Xershi 1555 08.03.17 12:57 Сейчас в теме
(1) делаешь выборку из колонки поле1, а затем вложенным запросом добавляешь поле 2 и 3.
10. Vovan58 64 09.03.17 01:17 Сейчас в теме
11. nikivr 09.03.17 09:49 Сейчас в теме
(10)
Прикрепленные файлы:
12. nikivr 09.03.17 09:53 Сейчас в теме
28. Xershi 1555 09.03.17 20:51 Сейчас в теме
(12) во вложенном запросе сделаешь через минимум и получишь свою первую! Ну или примерно так.
2. AskezaMax 07.03.17 23:54 Сейчас в теме
К примеру, можно пронумеровать записи запроса, а после группировки обернуть все еще одним запросом, где выберутся только записи, в которых Номер = 1.
Поищите примеры нумерации в запросе. Так, на вскидку, из интернета:
ВЫБРАТЬ
    Контрагенты.Наименование,
    1 КАК НомерСтроки
ПОМЕСТИТЬ ВТ
ИЗ
    Справочник.Контрагенты КАК Контрагенты
;
 
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
    Контрагенты.Наименование КАК Наименование,
    СУММА(ВТ.НомерСтроки) КАК НомерСтроки
ИЗ
    Справочник.Контрагенты КАК Контрагенты
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ КАК ВТ
        ПО Контрагенты.Наименование <= ВТ.Наименование
 
СГРУППИРОВАТЬ ПО
    Контрагенты.Наименование
 
УПОРЯДОЧИТЬ ПО
    НомерСтроки
Показать


Результат на примере таблиц
Таблица1:

Петров | 1
Иванов | 1
Сидовров | 1

Таблица2 (с соединением)
Петров | 1
Иванов | 1
Иванов | 1
Сидоров | 1
Сидоров | 1
Сидоров | 1

После группировки по 1-му полю:
Петров |1
Иванов|2
Сидоров|3
Михаська; +1 Ответить
5. nikivr 08.03.17 10:52 Сейчас в теме
(2) Да спасибо, про нумерацию я думал, но это конечно усложнит запрос. Думал может есть более простой способ

Но вот как пронумеровать каждую группу тоже в голову пока не приходит
18. v3rter 09.03.17 11:01 Сейчас в теме
Напрашивается ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ПЕРВЫЕ 1 ... ) но отпугивает упоминание неоптимальности в https://its.1c.ru/db/metod8dev#content:5842:hdoc:subquery_join
Возможно, получится с использованием метода из
(2)
и условия "ИМЕЮЩИЕ".

Нечто похожее есть тут: http://www.forum.mista.ru/topic.php?id=426553
19. herfis 513 09.03.17 11:10 Сейчас в теме
(18) "ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ ПЕРВЫЕ 1 ... )" - такое не взлетит. Это ж коррелирующий подзапрос предполагается, а в нем не получится наложить условия по данным первой таблицы. Или я не до конца понял, как вы предлагаете.
22. v3rter 09.03.17 12:29 Сейчас в теме
(19) Он самый. Получится, если использовать "В". Нашёл почти такой же пример у Гилева: http://www.gilev.ru/%D0%B2%D1%8B%D0%B1%D1%80%D0%B0%D1%82%D1%8C-%D0%B2-%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81%D0%B5-%D0%BE%D0%B4%D0%BD%D1%83-%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C-%D0%B8%D0%B7-%D0%BD%D0%B5%D1%81%D0%BA%D0%BE/

Этим же приемом я пользовался, когда пробовал себя в программировании под SQL, для исключения задвоений строк с данными из-за ошибочных задвоений в связанных через соединение справочниках. Скорость запроса падает, но достоверность результата 100%. В 1С это, похоже, запрещенный прием )
METRANDIR; 6385232; axsebur; Raskad; asupsam; herfis; +6 Ответить
23. herfis 513 09.03.17 12:46 Сейчас в теме
(22) Ключевая фраза "ПОЧТИ такой же". Да не такой. В "ГДЕ" основного запроса - там да, работает. Там доступны поля внешнего запроса. А в соединении поля из другой внешней таблицы доступны не будут.
Но сабжевую задачу как раз можно решить полностью аналогично примеру Гилева. Я забыл совсем, что "В" можно по нескольким полям накладывать сразу. Подобную конструкцию использовал, но только на одно поле.
7. Clancy08 08.03.17 11:44 Сейчас в теме
Добавляешь поле Приоритет
ВЫБОР КОГДА <Условие> ТОГДА 1 ИНАЧЕ 0 КОНЕЦ

Далее
МАКСИМУМ(Приоритет)
СГРУППИРОВАТЬ ПО
ПОЛЕ1

Далее к этой таблице внутренним соединением крепишь первую таблицу, по Приоритет и Значение.
9. mart-k667 09.03.17 01:00 Сейчас в теме
Нужно сначала сделать вложений запрос по Знач1,Знач2,Знач3, где выбрать различние.
а потом результат вложенго запроса связать внутренним соединением с основным набором даных.
elga2012; +1 Ответить
14. nikivr 09.03.17 10:10 Сейчас в теме
Если кто знает T-SQL может перевести этот запрос на язык 1С ?

SEL ECT top 1 with ties * FR OM [Table2]
order by row_number() over ( partition by Имя,Работа order by id )
15. ditp 94 09.03.17 10:14 Сейчас в теме
(14) Не получится перевести. В запросах 1С нет оконных функций (over ...).
16. nikivr 09.03.17 10:18 Сейчас в теме
(15) Может есть что-то другое, когда после преобразования в SQL получается (over...) ?
17. ResetAtreides 09.03.17 10:44 Сейчас в теме
(16) Нет. Да и вообще, какой смысл нумеровать порядок записей, если в запросе они могут появиться в произвольном порядке. Т.е. выбранная сейчас первая запись, во втором запросе может быть уже не первой
20. Euroset1 11 09.03.17 11:46 Сейчас в теме
Слово "первые" напрягает, одному ежу понятно, какая именно запись должна считаться первой. Ну да ладно, допустим первость здесь равносильна случайности.

Я где-то видел такой способ. Ключевое поле берем как есть, а второе берем агрегированно (например, макс). и группируем по ключевому. Но это было с двумя полями, ради третьего придется джойнить. Но попробовать можешь, суть думаю ясна.

Например, селект базтаб.поле1, макс(поле2) как поле2макс, поле3 фром базоваятаблица иннер джойн базоваятаблица как базтаб по поле3 = базтаб.поле3 и поле2макс = базтаб.поле2

вроде как-то так. И оно работало, но при условии того, что запись для каждого поле2---поле3 всегда одна и не более. Что касается оптимальности, то такой запрос летает.

p.s. на самом деле я забыл в "примере" про группировку. Конечно же, запрос с агрегацией должен быть без джоина и с группировкой по полю3, а уже следующий запрос должен взять этот запрос и джойнить с базовой таблицей. Но я же суть рассказываю все же, а не пытаюсь сделать все за автора.
21. ResetAtreides 09.03.17 12:28 Сейчас в теме
"Первую попавшуюся" можно, просто "Первую" - нельзя, т.к. нет признака, что именно эта строка - первая. Как отображается на форме - не показатель
24. herfis 513 09.03.17 12:55 Сейчас в теме
Получается, у Гилева приведено один в один решение сабжевой задачи :)
25. nikivr 09.03.17 14:23 Сейчас в теме
(24) У меня этот запрос отбирает все записи
27. herfis 513 09.03.17 15:56 Сейчас в теме
(25) А у меня как положено отрабатывает. На 8.3.6 клиент-сервер.
У Гилева там в конце приписка есть - "Кроме того, в некоторых версиях файлового варианта условие ГДЕ из-за ошибки платформы 8.2 не срабатывает."
Может, актуально до сих пор :)

ВЫБРАТЬ "Петя" КАК Ф, 1 КАК К1, 1 КАК К2, 1 КАК К3, 1 КАК К4
ПОМЕСТИТЬ Дано
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Петя", 2, 0, 0, 0
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Петя", 3, 0, 0, 0
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Вася", 5, 5, 5, 5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Вася", 7, 8, 9, 12
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Женя", 4, 4, 4, 4
;
ВЫБРАТЬ РАЗЛИЧНЫЕ Ф, К1, К2, К3, К4
ИЗ Дано
ГДЕ (Ф, К1, К2, К3, К4)
В (ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ Дано КАК ВСЁ ГДЕ ВСЁ.Ф = Дано.Ф)
Показать
METRANDIR; igor_polivin; TheOldGuard; Sa111ko; 6385232; Leits; CratosX; +7 Ответить
30. olbu 28.02.24 14:15 Сейчас в теме
(27)
ВЫБРАТЬ "Петя" КАК Ф, 1 КАК К1, 1 КАК К2, 1 КАК К3, 1 КАК К4
ПОМЕСТИТЬ Дано
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Петя", 2, 0, 0, 0
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Петя", 3, 0, 0, 0
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Вася", 5, 5, 5, 5
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Вася", 7, 8, 9, 12
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ "Женя", 4, 4, 4, 4
;
ВЫБРАТЬ РАЗЛИЧНЫЕ Ф, К1, К2, К3, К4
ИЗ Дано
ГДЕ (Ф, К1, К2, К3, К4)
В (ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ Дано КАК ВСЁ ГДЕ ВСЁ.Ф = Дано.Ф)
Показать


да и у меня на 8.2.19.102 Клиент-Сервер - выводит все записи...
31. user1050439 7 27.09.24 16:31 Сейчас в теме
(27) Спасибо, очень помогло. Я и не знал, что когда соединяешь в области ГДЕ с вложенной таблицей, то во вложенную таблицу передается ТЕКУЩАЯ ЗАПИСЬ основного запроса. Например

ВЫБРАТЬ 
	Т1.Группировка1,
	Т1.Поле1
ИЗ 
	ВТ КАК Т1 
ГДЕ 
	Т1.Поле1 В (
		ВЫБРАТЬ ПЕРВЫЕ 1
			Т2.Поле1 
		ИЗ
			ВТ КАК Т2 
		ГДЕ 
			Т2.Группировка1 = Т1.Группировка1)
Показать


Здесь видно во вложенной таблице фигурирует прямым образом (!) строка из основной таблицы Т1.*

То есть получается во вложенную таблицу передается текущая строка таблицы Т1, и можно сузить выборку таблицы 2 по ней, используя ГДЕ Т2.Группировка1 = Т1.Группировка1.
Оставьте свое сообщение

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