|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Например, есть таблица 1 Вася 1 Петя 1 Ваня 2 Аня 2 Таня 2 Маня Нужно получить 1 Вася 2 Аня ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 15:45 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Лунтик, "первые" - это в порядке возрастания recno() или как-то ещё? А если злобный хаксор Вова ночью откроет эту таблицу и воспользуется командой insert (не insert-sql, а просто insert), и получится у вас ab1Вася1Петя1Ваня2Вова2Аня2Таня2Маня, что тогда делать? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 15:56 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
tanglir, для простоты можно считать, что таблица упорядочивается как нужно непосредственно перед выборкой. Вообще, пытаюсь решить две задачи, в моем представлении, аналогичные по решению: 1. Выбирать первую операцию за день (период больше дня) 2. Найти первый вариант названия организации в списке строк с одинаковыми ИНН (из разных баз собирается консолидированная таблица контрагентов и получается, что для данного ИНН существует несколько вариантов реквизитов, главное чтобы они были из одной строки, т.е. поля не противоречили друг другу, например, КПП соответствовал бы адресу. Для данной задачи все равно какое значение возьмется, но ,наверно, логично, если возьмется первое) ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 16:09 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Первую задачу я бы делал через seek - он находит как раз первое значение А вот со вторым, по моему опыту, легче как раз брать последнюю запись: Код: plaintext 1.
авторглавное чтобы они были из одной строки, т.е. поля не противоречили друг другу Семь раз перечитал, чесслово. Не понял :-( ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 16:29 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Вот это да! Красивее не бывает - просто живописно! Почему это вообще работает? Что это за SET ENGINEBEHAVIOR 70? Как Вы на это вышли? Уважьте, Koryuu, напишите пару слов как этим пользоваться (HELP совсем невнятный). ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 17:02 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Лунтик, Включает режим совместимости SQL-заппросов для версий Visual FoxPro 7.0, 8.0, и 9.0. SET ENGINEBEHAVIOR 70 | 80 | 90 Параметры 70 Включает режим совместимости команд SQL в системе Visual FoxPro как в версиях, ниже 8.0. 80 Определяет выполнение команд SQL для версии Visual FoxPro 8.0. в следующей таблице описаны особенности данного режима. Опции SQL SELECT Поведение команды SELECT-SQL DISTINCT Вы не можете использовать опцию DISTINCT с полями типа Memo или General. Вместо этого используйте функции PADR( ) или ALLTRIM( ) для этих полей. Дополнительно см. Функции PADL( ) | PADR( ) | PADC( ) и функция ALLTRIM( ). UNION Опция UNION не поддерживается для полей типа Memo без предиката ALL, включенного в команду SQL SELECT. GROUP BY В опции GROUP BY должно быть указано поле из списка полей оператора SELECT , для которого выполняется агрегатная функция, такая как COUNT( ). Кроме того, опция GROUP BY должна содержать поле группировки, содержащееся в опции HAVING, исключая поля из агрегатных функций. Например, следующая команда генерирует ошибку в опции GROUP BY , потому, что поле company не указано в группировке. Копировать код SELECT company, country FROM Customer GROUP BY country Вы можете включать агрегатные функции в список SELECT без указания их в опции GROUP BY. Например, следующая команда использует COUNT( ) для поля company без указания его в опции GROUP BY . SELECT COUNT(company), country FROM Customer GROUP BY country HAVING Оператор SQL SELECT может содержать опцию HAVING без ссылки на опцию GROUP BY , при этом в операторе SQL SELECT не должно быть агрегатных функций. Например, следующая команда фильтрует запрос по заданной величине "Sweden". Копировать код SELECT customerid FROM customers HAVING country="Sweden" LIKE Оператор SQL SELECT автоматически не удаляет "хвостовые" пробелы для значений в конструкции LIKE. В предыдущей версии Visual FoxPro 7.0, в обеих переменных в конструкции LIKE, перед сравнением удалялись "хвостовые" пробелы . Например, В следующей команде выбираются данные из таблицы, имеющей следующие значения в каждой из строк, соответственно: "1.", "12 ", и "123". Копировать код SELECT * FROM table1 WHERE column1 LIKE "1__" В Visual FoxPro 7.0 и младших версиях в результате вернулась бы одна запись, со значением "123". В Visual FoxPro 8.0 в результат попадают три записи: , "1 ", "12 ", и "123". Если начальные символы совпадают, а следующие за ним удовлетворяют "маске", и имеют фиксированную длину, то конструкция LIKE обеспечивает их включение в результат запроса, "Хвостовые" пробелы не отбрасываются 90 Определяет выполнение команд SQL в соответствие со стандартными требованиями версии Visual FoxPro 9.0 (По-умолчанию) . В следующей таблице описаны особенности применения оператора SQL SELECT. Опции SQL SELECT Поведение команды SQL-SELECT TOP nExpr Когда используется данная опция: TOPnExpr[PERCENT] , команда SQL SELECT возвращает в результате не больше указанного количества записей: nExpr[PERCENT] . Дополнительно: SQL -средство в этом случае более эффективно использует доступную память и быстрее получает результат запроса, когда опция TOP указывается без ключевого слова PERCENT . GROUP BY Когда в запросе используется агрегатная функция, такая как MAX( ), и в команде SQL SELECT отсутствует конструкция GROUP BY , то записей в результате не будет, Visual FoxPro поместит в результат одну запись, системная переменная _TALLY будет = 1. В предыдущих версиях записей в результате не будет, _TALLY = 0. ORDER BY Команда SELECT … DISTINCT … ORDER BY генерирует ошибку если в опции ORDER BY указывается поле, которое отсутствует в списке полей команды SELECT . Копировать код CREATE CURSOR foo (f1 int, f2 int)SELECT DISTINCT f1 FROM foo ORDER BY f2 INTO CURSOR res HAVING Команда SELECT … DISTINCT … HAVING генерирует ошибку если в опции HAVING указано поле, отсутствующее в списке команды SELECT. Копировать код CREATE CURSOR foo (f1 int, f2 int)SELECT DISTINCT f1 from foo HAVING f2>1 INTO CURSOR res Комментарии Действие команды SET ENGINEBEHAVIOR является глобальным. Использование установки SET ENGINEBEHAVIOR = 70 может привести к неожиданным результатам при выполнении команды SQL SELECT с опциями DISTINCT и UNION для молей типа MEMO, а также при использовании опций GROUP BY , HAVING без указания конструкции GROUP BY, а также когда используется оператор сравнения LIKE . Когда используется установка SET ENGINEBEHAVIOR = 70 или = 80, относительно опции TOP в команде SQL SELECT в результат запроса может попасть более чем nExpr записей когда в команде также присутствует опция ORDER BY. Например, Вы задаете nExpr=10. Если в таблице имеется более чем 10 записей с одинаковым значением поля группировки, которое указано в опции ORDER BY , то в результате запроса будет больше чем 10 записей. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 17:12 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
ЛунтикНапример, есть таблица 1 Вася 1 Петя 1 Ваня 2 Аня 2 Таня 2 Маня Нужно получить 1 Вася 2 Аня Класс вопрос ! А у меня (гипотетически) есть таблица 1 Марь Иванна 1 Дядя Федя 2 Тётя из Куйбышева 2 Брат из Магадана И как мне красиво показать их дни рождения ? :) Чушь полная, пардон. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 19:00 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Лунтик2. Найти первый вариант названия организации в списке строк с одинаковыми ИНН (из разных баз собирается консолидированная таблица контрагентов и получается, что для данного ИНН существует несколько вариантов реквизитов, главное чтобы они были из одной строки, т.е. поля не противоречили друг другу, например, КПП соответствовал бы адресу. Для данной задачи все равно какое значение возьмется, но ,наверно, логично, если возьмется первое) Я бы крайне НЕ советовал менять настройку SET ENGINEBEHAVIOR. Вы получите большие проблемы при сопровождении программы. Когда понадобиться что-то изменить. В Вашем случае я бы пошел по пути исключения дублей еще на этапе формирования консолидированной таблицы. Т.е. просто не импортировать записи, если в общей базе уже есть запись с тем же ИНН. Значительно проще не собирать "мусор", чем потом от него избавляться. Задача поиска одной записи из группы может быть решена "стандартным" Select-SQL только в том случае, если есть некий уникальный идентификатор записи, хотя бы в пределах группы. Физический номер записи на эту роль не годится. Впрочем, этот идентификатор можно и создать. Но все-таки, лучше просто не накапливать "мусор". Еще раз. Не надо менять настройку SET ENGINEBEHAVIOR. Получите массу проблем в будущем. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 19:34 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Лунтик, Красиво отобрать не получиться, из г... пулю не сделать :) Если "как вообще отобрать" 1. Выборочка с группировкой по столбцу цифери, с полями "циферь" и "сколько записей с ней" 2. результат "присобачиваем" джойном к имеющемуся курсору, также добавляем поле-нумератор (в "промежуточном итого" имеем поля "номер", "строка", "кол-во строк с таким номером", "нумератор") 3. Нумератору даем значение "порядковое в пределах группы" Как это все выразить в запросе или нескольких - надеюсь - объяснять не надо В итоге получим N Name Cnt nInGr 1 Вася 3 1 1 Петя 3 2 1 Ваня 3 3 2 Аня 4 1 2 Таня 4 2 2 Маня 4 3 2 Дуня 4 4 Из чего делаете выборку примерно по WHERE nInGr == 1 ... |
|||
:
Нравится:
Не нравится:
|
|||
24.10.2011, 19:52 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Менять SET ENGINEBEHAVIOR нездоровое решение. Надежнее примерно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 09:03 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Пробую LOOKUP(ReturnField, eSearchExpression, SearchedField [, cTagName]) не совсем понятно насчет ReturnField,SearchedField: ReturnField:Определяет поле, содержание которого LOOKUP( ) возвращает в случае успешного поиска SearchedField:Определяет поле, в котором осуществлять поиск Указываю поля через алиас (ТаблицаГдеИскать.ИмяПоля) - вроде работает, указываю в качестве ReturnField RecNo() - вроде работает. Так что там можно указать: поле из текущей области или все-таки выражения да еще и из соседней области. И по скорости что-то не очень, наверное последний совет с index on поправильнее будет. А может установить SET ENGINEBEHAVIOR 70 непосредственно перед выборкой, а потом вернуть? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 11:58 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
ЛунтикПробую LOOKUP(ReturnField, eSearchExpression, SearchedField [, cTagName]) И по скорости что-то не очень, наверное последний совет с index on поправильнее будет. А может установить SET ENGINEBEHAVIOR 70 непосредственно перед выборкой, а потом вернуть? По скорости: без использования индексов всегда медленно, т.к. каждый раз происходит перебор всех записей до нахождения нужной. SET ENGINEBEHAVIOR - не гарантирует что попадет именно первая запись, то что обычно первая выбирается не значит что оно так всегда будет работать. Эта настройка появилась из-за того что до 7й версии у фокса был свой язык SQL, а после его привели в соответствии стандартам SQLя, а этот SET оставили чтобы старые проги могли работать без переписывания запросов. Использовать только SELECTы для твоей задачи нельзя, т.к. в SQLе нет вообще понятия номер записи, как следствие нет первой записи. Все записи равны и их порядок определяется только правилами сортировки. Поэтому надо использовать SCAN, если скорость критична, то можешь еще так попробовать: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 12:36 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Dima TSET ENGINEBEHAVIOR - не гарантирует что попадет именно первая запись, то что обычно первая выбирается не значит что оно так всегда будет работать. По условию задачи - не имеет значения первая, последняя или откуда-то из середины. Ему надо всего-лишь, чтобы ВСЕ поля были из одной записи таблицы-источника. Не только те, которые входят в группировку. Скорее всего, ЭТО условие будет соблюдаться. Хотя, согласен, что лучше настройку SET ENGINEBEHAVIOR не трогать Dima T Эта настройка появилась из-за того что до 7й версии у фокса был свой язык SQL, а после его привели в соответствии стандартам SQLя Немного не так расставлены акценты. Свой язык (точнее, диалект) SQL как был в FoxPro, так и остался. Его приблизили к стандарту. Dima TИспользовать только SELECTы для твоей задачи нельзя, т.к. в SQLе нет вообще понятия номер записи, как следствие нет первой записи. Все записи равны и их порядок определяется только правилами сортировки. Опять не вполне точно. Да, понятия порядкового номера нет. Но есть понятие "идентификатор записи". Если такой идентификатор существует в таблице, то задача может быть решена чистым Select. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17.
В принципе, этот самый идентификатор можно сконструировать искусственно в самом запросе используя для этой цели либо Recno(), либо Integer-Autoincrement (через CAST()). Т.е. сделать подзапросы. Вопрос в том, насколько это будет оправдано. Может, такое поле все-таки есть в таблице? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 14:12 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
На всякий случай, чтобы не было недоразумений. В приведенном запросе использовать в качестве идентификатора, например FIO - нельзя, поскольку нет гарантий уникальности этого самого FIO в пределах группы. А использовать все поля при сравнении на больше/меньше в одном запросе - бессмысленно. Неизвестно ведь в какой комбинации будут находится значения из разных записей. Нужен именно уникальный идентификатор записи. Primary Key. Который бы однозначно идентифицировал записи в таблице. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 14:23 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
- Привет? - Привет. Как звали того грузина котоый утопил в колодце гвозди? .... 30 часов молчания. P/S: Заржавелли. Вот вопрос такой. Ответ будет такой же. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 15:26 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
ВладимирМ , это то, что надо. У Вас всегда в заначке что-нибудь нужное. СПАСИБО! ... |
|||
:
Нравится:
Не нравится:
|
|||
25.10.2011, 16:36 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Код: plaintext
вообще не понятно из-за чего шум первым запросом в курсор выбираем по ключевым минимальную фамилию потом левое соединение иначе говоря операция в два действия 1. создаем курсор отбора 2. отбираем записи по условию ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 13:41 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
exists ладно ... но not exists в фоксе это граната в руках обезьяны левое соединение быстрее ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 13:43 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
sWinTyzвообще не понятно из-за чего шум первым запросом в курсор выбираем по ключевым минимальную фамилию потом левое соединение иначе говоря операция в два действия 1. создаем курсор отбора 2. отбираем записи по условию Теперь представим, что есть две записи с одинаковыми фамилиями. А если есть дубли в других полях? В общем случае, Вам придется повторить описанный цикл для КАЖДОГО поля записи. Кроме того, а при чем здесь именно левое объединение? Вы вообще в курсе для чего оно предназначено? sWinTyzexists ладно ... но not exists в фоксе это граната в руках обезьяны левое соединение быстрее Во-первых, для FoxPro, в общем случае , LEFT JOIN - не быстрее чем NOT EXISTS или NOT IN. Скорость выполнения будет примерно одинакова. Во-вторых, NOT EXISTS - вполне естесственно "переводится" на "человеческий" язык. Буквально. Здесь нет неоднозначности. "Не существует". Чего здесь непонятного-то? А вот LEFT JOIN практически все новички интерпретируют не адекватно. Постоянно справшивают, почему результат получается не такой, как вроде бы должен быть, если перевести как "присоединить к левой таблице" (а новички именно ТАК и "переводят"). А подобный перевод именно и вводит в заблуждение. Судя по Вашему предыдущему посту, Вы тоже не вполне понимаете для чего оно используется. Другими словами, если есть выбор между NOT EXISTS и LEFT JOIN, то используя NOT EXISTS меньше вероятность получить неожиданный (не ожидАемый) результат, чем при использовании LEFT JOIN ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 14:25 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
1. фамилии то может быть и две а группировочное поле одно да и минимум один 2. насчет NOT EXISTS даже не знаю что сказать .... я думал это я читал рекомендации Базеяна черная толстая книга если помните но видимо память меня сдает ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:21 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
кстати полученный курсор насколько я помню можно использовать в опции IN () там вроде через запятую можно поля указать ? ну если нельзя тогда пожно собрать строку но это будет дольше так что способов явно больше чем два а вообще не знаю я от фокса отшел человеку который так долго сидит на фоксе конечно виднее ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:27 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
sWinTyz1. фамилии то может быть и две а группировочное поле одно да и минимум один Вы точно понимаете о чем говорите? Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11.
Или как Вы себе представляете второй запрос? ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:30 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
вообще Вы правы что там крутили с recno() на фоксе в старых таблицах нет ИД но рекномер есть за три запроса можно сделать это но все это как то не быстро ... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:35 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
эх ... коротка кольчужка ... Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:43 |
|
Как красиво отобрать первые встретившиеся записи?
|
|||
---|---|---|---|
#18+
Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9.
... |
|||
:
Нравится:
Не нравится:
|
|||
26.10.2011, 15:44 |
|
|
start [/forum/topic.php?fid=41&fpage=6&tid=1581604]: |
0ms |
get settings: |
8ms |
get forum list: |
13ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
52ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
64ms |
get tp. blocked users: |
2ms |
others: | 297ms |
total: | 456ms |
0 / 0 |