:: Visual Foxpro, Foxpro for DOS
SELECT, агрегирующая функция и GROUP BY
ProbaSP

Сообщений: 94
Откуда: Урал
Дата регистрации: 28.01.2016
Привет Всем!
Вот рабочий пример запроса:

SELECT MAX(.f.) as vibor, company, country FROM Customer GROUP BY company, country INTO CURSOR kVibor READWRITE

НО теперь в созданном курсоре(kVibor) значения полей company, country перегруппировались, а нужно чтоб остались в том порядке в каком были в таблице Customer(это, к сожалению, для меня важно ).
Подскажите, как можно решить этот вопрос...(или ткните, где это уже разбиралось)
Спасибо.
VFP9 SP2
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
PaulWist

Сообщений: 14614
Дата регистрации: 01.04.2004
Дык, репо код приведи, типа было так, стало так, а надо вот так.


------------------
Есть многое на свете, друг Горацио...
Что и не снилось нашим мудрецам.
(В.Шекспир Гамлет)
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Если исходная таблица DBF, то RECNO() записей также извлеки, и по нему ORDER-ни
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Никак нельзя сохранить какой-то "физический порядок" даже в неагрегирующем запросе. SQL НЕ работает с такими понятиями - для него все записи "строки" равнозначны и НЕупорядочены - движок выполнения запроса не обязан их просматривать "в физическом порядке" или в каком-то "индексном" заданном через SET ORDER.
Нужно сделать нормальный ID или что-то типа того, включить его в запрос (например используя функции MIN() или MAX() - группировать по нему не нужно) и использовать в опции ORDER BY. В принципе можно использовать в качестве такого id функцию recno() побаловавшись с подзапросами - но это решение глубоко через ж*** (велика вероятность что сделать стабильно работающий запрос ты не сможешь, только усложнишь себе жизнь последующим отловом непредсказуемых ошибок), и для целей использования в рабочем коде крайне не советую. Если уж совсем плохо, то хотя бы за 2 запроса это делай - в первом просто выборка в курсор всех нужных полей плюс RECNO() и строго из ОДНОЙ таблицы (в однотабличных запросах RECNO() без параметров худо-бедно работает, и можно пойти на такую "некрасивость"). А уже во втором запросе и делать выборку с MAX(это_вычисленное_поле) и ORDER BY 1 ну или какое оно там по порядку окажется.

При этом надо решить какой порядок будет правильным. Т.к. в таблице запросто может быть записано (для простоты только страну возьмём, для 2 полей ситуация аналогична)
"RU", 10
"US", 20
"US", 24
"RU", 33

Ну и какой по порядку в агрегирующем запросе должна быть RU - первой или последней? В зависимости от этого и выбирай функцию MAX или MIN, или даже AVG если нужна особо хитро-вывернутая сортировка, скажем "большинство RU записей было в исходной таблице в начале, значит его первым ставим".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
ProbaSP

Сообщений: 94
Откуда: Урал
Дата регистрации: 28.01.2016
Спасибо!
С RECNO() все получилось.

SELECT MAX(.f.) as vibor, company, country, RECNO() as rec FROM Customer GROUP BY rec, company, country INTO CURSOR kVibor READWRITE

По крайней мере результат меня устраивает...



Исправлено 1 раз(а). Последнее : ProbaSP, 17.11.17 15:54
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
При группировке по recno пропадает всяческий смысл в агрегации.
Впрочем, смысла в конструкции MAX(.f.) as vibor тоже нет совершенно никакого. Для создания нового поля из константного значения не нужна агрегирующая функция, даже в запросе с группировкой.
Т.е. либо изначально в этом запросе не нужна никакая группировка (если сочетание полей company, country всегда уникально для данной таблицы), либо запрос попросту не будет ничего агрегировать, т.е. не будет убирать "дубликаты" в сочетаниях компании и страны.

Пример, сразу с ПРАВИЛЬНЫМ решением, включающим изменение структуры исходной таблицы - чтобы "порядок записей" определялся по содержимому конкретного поля, а не по "физическому порядку".

CREATE CURSOR Customer (id I AUTOINC, company C(10), country C(2))
INSERT INTO Customer (company, country) VALUES ("c1","ru")
INSERT INTO Customer (company, country) VALUES ("c2","us")
INSERT INTO Customer (company, country) VALUES ("c3","us")
INSERT INTO Customer (company, country) VALUES ("c3","ru")
INSERT INTO Customer (company, country) VALUES ("c1","ru")
INSERT INTO Customer (company, country) VALUES ("c2","us")
INSERT INTO Customer (company, country) VALUES ("c3","ru")
INSERT INTO Customer (company, country) VALUES ("c3","us")
SELECT .f. vibor, company, country, MIN(id) number_in_order FROM Customer GROUP BY company, country ORDER BY 4 INTO CURSOR res
* Если сделать по уму не дают, можно "эмулировать" такое поле id при помощи функции recno()
* Лучше (понятнее и надёжнее) в 2 приёма
SELECT company, country, RECNO() rn FROM Customer INTO CURSOR tmp
SELECT .f. vibor, company, country, MIN(rn) number_in_order FROM tmp GROUP BY company, country ORDER BY 4 INTO CURSOR res
* Если охота сломать мозг, то можно и "за 1 ход" - но эту мульку я бы НЕ советовал применять.
SELECT .f. vibor, company, country, MIN(rn) number_in_order FROM ;
(SELECT company, country, RECNO() rn FROM Customer) tmp ;
GROUP BY company, country ORDER BY 4 INTO CURSOR res
Можешь на этом примере и свой запрос запустить и увидеть что он НЕ агрегирует ничего, т.е. оставит дубли.
Если в таблице изначально дублей (по этим 2 полям) нет, то достаточно тривиального
SELECT .f. vibor, company, country FROM Customer INTO CURSOR res


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Да, не понятно, зачем ТС затеял группировку. Обычно это нужно, чтобы просуммировать деньги например, для каждой пары {страна, кампания}, и обычно порядок неважен... Может ТС хотел просто упорядочить... но зачем тогда " нужно чтоб остались в том порядке в каком были в таблице Customer"
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
ProbaSP

Сообщений: 94
Откуда: Урал
Дата регистрации: 28.01.2016
Ну вообще разобрался...
собственно, мне ни какая группировка-то не нужна.
просто когда-то of63 мне показал пример, как можно добавить "столбец" (значения в нём должны были быть 1 или 0) при запросе.
поэтому
MAX(.f.) as vibor
я применял не задумываясь. а когда появляется в запросе агрегирующая функция то без GROUP BY не обойтись.
вот я и запутался(вернее сам себя запутывал)...
а вы мне тут всё разжевали и ещё определили что она там не нужна(группировка)!
ВСЕМ ОГРОМНОЕ СПАСИБО!

p.s. убрал MAX(), GROUP BY. И про RECNO() опыт добавился.

а оказывается делов-то:
SELECT .f. as vibor, company, country FROM Customer INTO CURSOR kVibor READWRITE
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
of63

Сообщений: 25240
Откуда: Н.Новгород
Дата регистрации: 13.02.2008
Что за "MAX(.f.) as vibor" я проповедовал?
Ratings: 0 negative/0 positive
Re: SELECT, агрегирующая функция и GROUP BY
Simple777
Автор

Сообщений: 33855
Дата регистрации: 05.11.2006
of63
Что за "MAX(.f.) as vibor" я проповедовал?

Таковы гении - порождая новые смыслы, теряют в дальнейшем к ним интерес и предают забвению!.. :bi:

И только изумлённые потомки спустя многия годы постигают смысл извергнутого.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 23 (Гостей: 23)

© 2000-2024 Fox Club 
Яндекс.Метрика